Anti-Censorship Mirror & Security Tool

📡 The Taylor Wessing Data Breach Toolkit

Universal Forensic Audit & Layer Decomposition Suite to expose and unmask visual-only PDF redactions by Taylor Wessing LLP and Valve Corporation.

Censorship Resistance

This toolkit and its related case studies are mirrored here permanently. Any legal threats, DMCA take-downs, or attempts at intimidation by Taylor Wessing LLP or Valve Corporation will be treated as public, undeniable proof of trying to censor security research and cover up technical incompetence.

Forensic PDF analysis
Forensic PDF Audit: Recreating and examining document drawing layers to strip fake black-box vector overlays and extract raw unredacted text.

🔍 Executive Summary

The Universal PDF Redaction Auditor & Layer Decomposer is a professional, offline-first forensic auditing and layer decomposition suite specifically engineered to identify, verify, and sanitize visual-only PDF redaction vulnerabilities. This toolkit serves as an open-source utility for security researchers, data protection officers, and compliance auditors to verify document structural integrity before public disclosure.

⚖️ Technical Power Asymmetry

This auditing utility is built to address a critical power imbalance in corporate data processing. When massive conglomerates (such as Valve Corporation) are represented by elite law firms (such as Taylor Wessing LLP), any systematic data exposure doesn't hurt the corporation or their high-priced lawyers—it catastrophically compromises the privacy of their opponents (the individual data subjects, third-party users, and minors whose sensitive personal data is leaked due to legal and technical negligence). This toolkit empowers individuals and independent auditors to verify data safety and hold corporate actors accountable.

📊 Case Study: The Taylor Wessing / Valve GDPR Leak

During the processing of GDPR Article 15 Subject Access Requests (SARs) regarding Steam user data, a critical security vulnerability was identified in documents processed and dispatched by external counsel Taylor Wessing LLP on behalf of Valve Corporation.

Technical Failure Analysis

Instead of permanently sanitizing the raw character arrays inside the PDF content streams, an automated, custom PDF generation pipeline (utilizing Aspose.PDF for .NET) was deployed. This system programmatically queried coordinates of sensitive fields and drew solid black vector shapes (using PDF's re and f/F/b/B operators) on top of the text.

Because visual drawing layers do not alter or destroy the raw text arrays underneath, thousands of unredacted private records—including account credentials, logins, emails, security logs, and de-anonymized data of minors—remained fully intact, copyable, and extractable from the dispatched files.

📂 Exhibit A: Leaked Correspondence with Dr. Patrick Zurheide

Below is the exact response received from Dr. Patrick Zurheide (Salary Partner at Taylor Wessing LLP) after PhishDestroy formally notified the firm of their PDF redaction failure and the subsequent leak of Steam users' data. Instead of initiating a GDPR Article 33 breach notification, he chose to write this:

"Guten Tag PhishDestroy-Team,

Vielen Dank für Ihre anscheinend übersetzte, aber durchaus unterhaltsame Nachricht. Auf welche Kommunikation „mit strafrechtlicher Verfolgung“ an das PhishDestroy-Team referenzieren Sie denn? Ich bin mir sicher mit PhishDestroy in keiner Form jemals zuvor kommuniziert zu haben. Bitte stellen Sie diese angebliche Kommunikation daher bereit, um zu verstehen, worum es überhaupt geht.

Ihrem Schreiben ist inhaltlich leider schwer bis gar nicht zu folgen. Als Hinweis: Ein Disclaimer, wie unten in Ihrem Schreiben, was vermeintlich nicht gemacht/beabsichtigt wird, ist bedeutungslos, wenn diesem die eigentlichen Handlungen entgegenstehen.

Patrick Zurheide"

🔍 PhishDestroy Analysis:

  • "unterhaltsame Nachricht" (entertaining message): A highly paid "IT Law Expert" called a forensic notification of a massive GDPR data leak involving minors' exposed Steam accounts "entertaining."
  • "schwer bis gar nicht zu folgen" (impossible to follow): We provided him with exact hex-values, the metadata of his PDF, the 36-second batch pipeline timestamps, and the specific Aspose 20.8 version causing the leak. Apparently, IT metrics are too "difficult to follow" for a Doctor of IT Law.

🛠️ Multi-Tool Capabilities

This suite offers three complementary, fully client-side modes to analyze and dismantle fake visual redactions:

  • 📡 Mode 1: X-Ray Scanner (PDF.js): Renders the visual PDF displays but pulls the underlying unredacted text characters in real-time. You see the black box, but you read the secret instantly.
  • ✂️ Mode 2: Layer Stripper (PDF-Lib): Surgical stream-level sanitization. Physically replaces rectangular visual paint commands (re f, re F) with the n (no-paint) operator, deleting the black bars.
  • 🔎 Mode 3: Collision Audit (Fitz Layout): Highlights overlapping text and graphics to generate automatically compiled lists of leaks.

💻 CLI Usage (decensor.py)

# 1. Decompose PDF to raw text layers (Strips all drawings, lines, and masks globally)
python decensor.py -i compromised.pdf -d -o naked_document.pdf

# 2. Extract and save all text hidden under black visual shapes to a leaks text report
python decensor.py -i compromised.pdf -e verified_leaks.txt

# 3. List page-by-page structural element counts
python decensor.py -i compromised.pdf -l

🔍 Core Python Stream Sanitizer

import re, fitz

def strip_black_bars_global(input_path, output_path):
    doc = fitz.open(input_path)
    for xref in range(1, doc.xref_length()):
        if not doc.is_stream(xref):
            continue
        try:
            obj_dict = doc.xref_object(xref)
            if any(m in obj_dict for m in ["/Type /Font", "/Subtype /Image", "/Type /Halftone"]):
                continue
                
            stream_bytes = doc.xref_stream(xref)
            text = stream_bytes.decode('latin-1')
            
            # Swap rectangular painting operators with no-fill 're n', preserving newlines
            modified_text, count = re.subn(
                r'\bre\s+([fFbB]\*?)(?=\s|$)',
                lambda m: f"re{m.group(0)[2:-len(m.group(1))]}n",
                text
            )
            if count > 0:
                doc.update_stream(xref, modified_text.encode('latin-1'))
        except Exception:
            continue
    doc.save(output_path, garbage=4, deflate=True, clean=True)
    doc.close()