Back to skill

Security audit

Pdf Contract Redactor

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent contract-redaction purpose, but its implementation can leave or recreate sensitive contract data despite appearing to redact it.

Review before installing. Do not use this skill for confidential contracts unless you accept Alibaba Cloud upload of document pages and the risk that generated outputs, logs, or sidecar JSON files may still expose the values you intended to hide. Prefer a version that uses secure PDF redaction or page rasterization, avoids plaintext value export by default, removes sensitive stdout logging, and uses safer credential handling.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/redact_contract.py:204
Finding
Redacted PDF Retains Recoverable Underlying Content## Vulnerability Details **File Location**: `scripts/redact_contract.py:204-217` **Vulnerability Type**: Insecure visual-only redaction **Risk Level**: High **Vulnerable Code**: ```python for page_num, page_values in values_by_page.items(): if page_num >= len(doc): continue page = doc[page_num] for fv in page_values: x0, y0, x1, y1 = fv.value_bbox pdf_x0, pdf_y0 = x0 * scale, y0 * scale pdf_x1, pdf_y1 = x1 * scale, y1 * scale padding = 3 rect = fitz.Rect(pdf_x0 - padding, pdf_y0 - padding, pdf_x1 + padding, pdf_y1 + padding) page.draw_rect(rect, color=(0, 0, 0), fill=(0, 0, 0)) doc.save(output_path) doc.close() ``` ### Technical Analysis The implementation draws opaque rectangles over sensitive values but does not remove the underlying PDF text, image pixels, or content streams. An opaque drawing operation is a visual overlay rather than a secure redaction operation. Existing text may remain available through text extraction, while scanned image pixels remain embedded beneath the rectangle. PDF editing or forensic tools may also permit removal or bypass of the overlay object. Consequently, the generated file can appear redacted while continuing to contain the original confidential information. ### Attack Path 1. A user processes a confidential contract and distributes the generated redacted PDF. 2. An attacker obtains that PDF without requiring access to the source document. 3. The attacker uses a PDF editor, object inspector, text extractor, or content-stream parser. 4. The attacker removes or bypasses the rectangle objects, extracts underlying text, or recovers the original scanned image. 5. Sensitive contract values hidden by the visual overlays are disclosed. ### Impact Assessment This issue can disclose identities, telephone numbers, addresses, bank accounts, contract amounts, project identifiers, and other contract data. ...[truncated 160 chars]
Remediation
## Remediation Suggestions - Use PyMuPDF redaction annotations and invoke the API that permanently applies those redactions. - Save the result with appropriate garbage collection and content cleaning so removed objects are not retained. - For scanned contracts, flatten each finalized redacted page into a new raster image and construct a new image-only PDF. - Ensure metadata, embedded files, annotations, alternate image representations, and OCR text layers are also sanitized. - Add automated tests that attempt text extraction, object removal, image extraction, and content-stream inspection on generated files. - Do not describe an output as securely redacted unless these recovery tests fail.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/redact_contract.py:220
Finding
Sensitive Redacted Values Are Exported to a Plaintext JSON Sidecar## Vulnerability Details **File Location**: `scripts/redact_contract.py:220-224` **Vulnerability Type**: Plaintext storage of sensitive information **Risk Level**: High **Vulnerable Code**: ```python def export_results(self, field_values: List[FieldValue], output_path: str) -> None: data = [{"field_name": fv.field_name, "value": fv.value, "page": fv.page + 1, "field_bbox": fv.field_bbox, "value_bbox": fv.value_bbox} for fv in field_values] with open(output_path, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) ``` The export is invoked unconditionally: ```python json_path = output_pdf.replace('.pdf', '_fields.json') redactor.export_results(field_values, json_path) ``` ### Technical Analysis The JSON sidecar stores every recognized value that the tool is intended to conceal. The data is written in plaintext with default filesystem permissions and without encryption, access-control validation, retention controls, or an explicit user opt-in. This creates a second copy of the confidential information and undermines the privacy objective of producing a redacted document. Depending on the process umask and destination directory, the file may be accessible to other local users, backup services, synchronization tools, or anyone receiving the output directory. ### Attack Path 1. A user runs the redactor on a sensitive contract. 2. The script automatically creates a `_fields.json` file next to the output PDF. 3. The sidecar contains field names and their complete unredacted values. 4. Another local user, backup operator, synchronization service, malware process, or accidental recipient reads the file. 5. The supposedly redacted contract data is recovered directly without attacking the PDF. ### Impact Assessment The exposure covers all matched values, potentially including names, phone numbers, mailing addresses, invoice and payment details, bank accoun ...[truncated 221 chars]
Remediation
## Remediation Suggestions - Do not generate a sidecar containing confidential values by default. - If diagnostics are required, make export an explicit opt-in option and omit or irreversibly hash recognized values. - Create diagnostic files with restrictive permissions such as `0600`. - Support an explicitly selected, access-controlled output directory. - Encrypt any operationally required sensitive export and define a short retention period. - Document secure deletion, backup, and sharing requirements. - Prefer aggregate results such as field names, match counts, confidence ranges, and page numbers without storing the values.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/redact_contract.py:246
Finding
Sensitive Contract Values Are Printed to Standard Output## Vulnerability Details **File Location**: `scripts/redact_contract.py:246-247` **Vulnerability Type**: Sensitive information exposure through logs **Risk Level**: High **Vulnerable Code**: ```python for fv in field_values[:10]: print(f" [{fv.field_name}] = {fv.value[:30]}") ``` ### Technical Analysis The script prints up to the first 30 characters of the first ten recognized sensitive values. Standard output is commonly captured by terminals, CI/CD systems, task runners, agent transcripts, centralized logging platforms, and monitoring systems. Truncation does not provide meaningful protection because many relevant values—including names, telephone numbers, account numbers, dates, and monetary amounts—fit entirely within 30 characters. ### Attack Path 1. The redactor runs interactively, through an agent, or in an automated job. 2. Matched confidential values are printed to standard output. 3. A terminal recorder, job runner, agent transcript, or logging service retains the output. 4. A user with access to those logs reads the confidential contract values. 5. The information persists independently of deletion or protection of the generated PDF. ### Impact Assessment The issue can expose up to ten matched values per execution to every system or user authorized to collect or read process output. It does not grant system privileges, but it expands sensitive-data access to logging and operational personnel who may not be authorized to inspect contract contents.
Remediation
## Remediation Suggestions - Remove all logging of recognized values. - Log only non-sensitive status information, such as page counts, match counts, and opaque identifiers. - If detailed debugging is essential, require an explicit debug option and redact or hash all values. - Disable sensitive debug output in production and agent-driven environments. - Review existing terminal, CI, and centralized logs for exposed values and apply appropriate retention or deletion procedures.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/redact_contract.py:228
Finding
Alibaba Cloud Credentials Are Supplied Through Process-Visible Command-Line Arguments## Vulnerability Details **File Location**: `scripts/redact_contract.py:228-234` **Vulnerability Type**: Insecure credential handling **Risk Level**: Medium **Vulnerable Code**: ```python def main(): if len(sys.argv) < 4: print("Usage: python redact_contract.py <input.pdf> <access_key_id> <access_key_secret> [output.pdf]") sys.exit(1) input_pdf = sys.argv[1] access_key_id = sys.argv[2] access_key_secret = sys.argv[3] ``` The documented invocation also instructs users to place credentials on the command line: ```bash python scripts/redact_contract.py contract.pdf LTAIxxx xxx contract_redacted.pdf ``` ### Technical Analysis Command-line arguments may be exposed through process listings, shell history, job definitions, audit telemetry, crash reports, and automation logs. Local users or monitoring services able to inspect process metadata may recover both the access-key ID and secret. The implementation also stores the secret in the client object, but the observed custom request does not use it to compute a request signature. The access-key ID is included in URL query parameters. This suggests incomplete custom authentication handling and unnecessarily exposes credential material. ### Attack Path 1. A user follows the documented command and places long-lived cloud credentials in process arguments. 2. The command is recorded in shell history or an automation system, or is observed while running through process inspection. 3. An attacker or unauthorized operator obtains the access-key ID and secret. 4. The attacker authenticates to Alibaba Cloud using those credentials. 5. The attacker accesses any cloud resources and API operations permitted by the associated identity. ### Impact Assessment The resulting privileges are bounded by the Alibaba Cloud permissions assigned to the compromised identity. If the credentials are not restricted to OCR, the exp ...[truncated 208 chars]
Remediation
## Remediation Suggestions - Remove cloud secrets from command-line arguments. - Use Alibaba Cloud's official SDK and standard credential-provider chain. - Prefer short-lived credentials supplied through a protected credential file, workload identity, instance role, or environment-based secret injection. - Apply restrictive file permissions to any credential configuration. - Assign an OCR-only role with the minimum required API permissions and enforce rotation and expiration. - Ensure credentials and signed request details are not written to URLs, logs, exceptions, or telemetry. - Rotate any credentials previously used through command-line invocations if process or shell history may have retained them.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:110
Finding
Installation Instructions Use Unpinned Third-Party Dependencies## Vulnerability Details **File Location**: `SKILL.md:110` **Vulnerability Type**: Unpinned software supply-chain dependencies **Risk Level**: Medium **Vulnerable Code**: ```bash pip install pymupdf pillow requests ``` ### Technical Analysis The installation command retrieves the latest versions selected by the package index and resolver at installation time. No reviewed versions, integrity hashes, lock file, or reproducible dependency set is specified. This does not establish that any named dependency is currently malicious. However, it permits future, compromised, or incompatible releases to enter the execution environment without corresponding review. Python packages and their transitive dependencies may execute installation-time or runtime code with the privileges of the user running `pip` or the Skill. ### Attack Path 1. A user follows the documented installation command. 2. The package resolver selects versions available at that time rather than a reviewed dependency set. 3. A dependency account, package release, package index, or transitive dependency is compromised. 4. The malicious version is downloaded and installed. 5. Installation hooks or imported package code execute with the invoking user's privileges. ### Impact Assessment Successful supply-chain exploitation could read or modify files available to the installing user, access contract documents and cloud credentials, make network requests, or alter generated outputs. The local scope is limited by the privileges of the account or environment running the installation, but running the command with administrative privileges would increase the impact.
Remediation
## Remediation Suggestions - Pin reviewed direct and transitive dependency versions in a lock file. - Record and enforce cryptographic hashes using `pip --require-hashes`. - Install dependencies in a dedicated virtual environment without administrative privileges. - Use a trusted package index or controlled internal mirror. - Automate vulnerability and provenance scanning for dependency updates. - Review and test updates before changing the locked dependency set. - Consider distributing a reproducible, signed environment manifest.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Missing User Warnings

High
Confidence
97% confidence
Finding
The tool sends full page images of scanned contracts to a third-party OCR endpoint, which may contain highly sensitive legal, financial, and personal information. In this skill context, undisclosed off-device transmission is especially dangerous because users may expect local redaction, not external processing by a cloud provider.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill describes capabilities that require network access to Alibaba Cloud OCR and local file creation for redacted PDFs/JSON, but it does not declare tool scope or permissions. In an agent environment, undeclared capabilities reduce transparency and can enable unintended data egress or file modification beyond what users expect.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
This skill processes scanned contracts, which commonly contain highly sensitive legal, financial, and personal data, and sends page images/text to Alibaba Cloud OCR. Failing to warn users about third-party transmission creates a real privacy and compliance risk because users may unknowingly disclose confidential contract contents to an external service.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The documented JSON output contains matched field-value pairs, which can preserve the very sensitive data the PDF redaction is meant to protect. If users assume the workflow produces only a safe redacted PDF, the sidecar JSON can become a hidden leakage channel that exposes confidential values to other users, processes, or storage systems.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The module description states that the tool redacts field values, but the implementation also preserves those values in a plaintext JSON artifact. This mismatch can mislead users into believing sensitive data is being removed when it is actually being copied to another location, increasing the chance of accidental exposure.

External Transmission

Medium
Category
Data Exfiltration
Content
body = {"ImageURL": f"data:image/png;base64,{image_base64}", "OutputFigure": False}
        
        try:
            response = requests.post(url, params=params, json=body, timeout=60)
            result = response.json()
            
            if "Code" in result and result["Code"] != "Success":
Confidence
90% confidence
Finding
This request transmits contract image data to an external network service. External transmission is not inherently malicious here because OCR is the stated purpose, but it is still a real security concern in a contract-redaction tool since the uploaded material may include sensitive business and personal data.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The script writes extracted field values from contracts to a plaintext JSON sidecar file, which expands the tool's behavior from redaction into data retention and disclosure. Because the values being processed are precisely the sensitive items intended for redaction, this creates a clear confidentiality risk if the filesystem, logs, backups, or downstream tooling are accessed.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script writes detected contract field values to disk without notifying the user that sensitive contract contents will be stored locally in plaintext. This is risky because users invoking a redaction tool may not anticipate creation of an additional sensitive artifact that can persist in work directories, backups, or shared storage.

Natural-Language Policy Violations

Low
Confidence
72% confidence
Finding
The description specifically states support for Alibaba Cloud OCR for accurate Chinese text recognition, effectively steering usage toward a single language/locale path. The file does not offer user opt-in for language handling or explain that the skill is intentionally limited to Chinese-language contract workflows.

Static analysis

No suspicious patterns detected.