Back to skill

Security audit

Pdf Pro

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent PDF utility, but it needs Review because it handles PDF passwords insecurely and offers decryption without authorization guidance.

Review before installing if you will process sensitive PDFs. Use it only on documents you own or are authorized to modify, avoid passing passwords on the command line, avoid recorded/shared terminals for encryption or decryption, and install dependencies in a virtual environment with pinned versions where possible.

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 (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:48
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:48
Vulnerability Type: Unpinned third-party dependencies
Risk Level: Medium

Vulnerable code snippet:

shell
pip install PyPDF2 pdfplumber Pillow reportlab pypdfium2

Technical Analysis

The documented installation command resolves the latest package versions available from the configured Python package index. It does not use exact versions, a reviewed lock file, or package integrity hashes. Consequently, two installations at different times can retrieve different code even though the Skill package itself has not changed.

The package names are consistent with the declared functionality, and the audit found no evidence of typosquatting or an intentionally malicious dependency. Nevertheless, mutable dependency resolution creates a supply-chain exposure: compromise of a listed package, one of its transitive dependencies, or the package-index account used to publish it could introduce malicious code into future installations.

Attack Path

  1. An attacker compromises a referenced package, a transitive dependency, or its publication account.
  2. The attacker publishes a malicious release that still satisfies the unrestricted installation command.
  3. A user follows the installation instructions after that release becomes available.
  4. pip resolves and installs the attacker-controlled version.
  5. Malicious installation hooks or runtime code execute with the privileges of the user or service account performing the installation or running the PDF tool.

Impact Assessment

Successful exploitation could execute arbitrary code with the privileges of the account installing or invoking the dependency. Depending on those privileges, this could expose documents accessible to the account, modify user-owned files, steal environment credentials, or compromise the environment where the Skill runs. The audit did not find evidence that such compromise is currently ...[truncated 11 chars]

Remediation
View remediation

Remediation Suggestions

  • Create a reviewed dependency lock file containing exact versions for all direct and transitive dependencies.
  • Add cryptographic hashes and install with:
    shell
    pip install --require-hashes -r requirements.txt
    
  • Remove the unrestricted installation command from the documentation or replace it with the locked installation procedure.
  • Use an isolated virtual environment and avoid installing packages with administrator or root privileges.
  • Periodically scan locked packages for known vulnerabilities and update them through a controlled review process.
  • Consider using a trusted internal package mirror with package allowlisting and provenance verification.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pdf_tools.py:420
Finding

PDF Passwords Exposed Through Echoed Input and Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/pdf_tools.py:420, scripts/pdf_tools.py:426, scripts/pdf_tools.py:499-508
Vulnerability Type: Insecure handling of sensitive authentication data
Risk Level: Medium

Vulnerable code snippets:

python
password = input("输入密码: ").strip()
python
password = input("输入密码: ").strip()
python
elif command == 'encrypt':
    if len(args.args) < 3:
        print("用法: pdf-tools encrypt <file.pdf> <output.pdf> <password>")
    else:
        tools.encrypt(args.args[0], args.args[1], args.args[2])

elif command == 'decrypt':
    if len(args.args) < 3:
        print("用法: pdf-tools decrypt <file.pdf> <output.pdf> <password>")
    else:
        tools.decrypt(args.args[0], args.args[1], args.args[2])

Technical Analysis

Interactive encryption and decryption use Python's input() function. Terminal input collected this way is normally echoed, so the password is visible to observers, screen-recording software, terminal logging systems, and potentially retained scrollback.

In command-line mode, the password is accepted as the third positional argument. Command-line arguments may be recorded in shell history, job logs, process-monitoring systems, audit telemetry, crash diagnostics, and, depending on operating-system configuration, process listings available to other local users.

The password is not hardcoded and the code does not transmit it over a network. The vulnerability is the unnecessary exposure of a user-provided secret through observable input channels.

Attack Path

Interactive-input path:

  1. A user selects the PDF encryption or decryption operation.
  2. The program obtains the password with input().
  3. The terminal echoes the password while it is entered.
  4. A nearby observer, terminal logger, screen recorder, or remote-session recording captures the value.
  5. The ...[truncated 1010 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace interactive password reads with non-echoing input:
    python
    from getpass import getpass
    
    password = getpass("Enter password: ")
    
  • Remove password values from positional command-line arguments.
  • Securely prompt for the password when the encrypt or decrypt command is selected.
  • For non-interactive automation, accept the secret through a protected file descriptor, operating-system credential service, or secret-management integration rather than through command arguments or environment variables.
  • Avoid logging password values and sanitize diagnostic output that could contain the original argument vector.
  • Clear references to the password as soon as practical, while recognizing that Python strings cannot be reliably erased from memory.
  • Warn users against password reuse and recommend executing sensitive operations in environments without terminal recording or untrusted local users.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (4)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill explicitly offers PDF decryption and encryption, including removal of password protection, but provides no warning that these actions should only be performed on files the user is authorized to modify. In an agent context, this can normalize or facilitate unauthorized access to protected documents and weakens security expectations around handling sensitive files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest presents the skill's display name and description only in Chinese, with no indication that users can choose another language or that the skill is intended solely for a Chinese-speaking or region-specific environment. This can violate language/locale policy expectations when a skill is distributed broadly without explicit opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code file contains natural-language strings that force a specific language/locale for all user interaction, including the module description and later prompts/errors. Under the policy, locale constraints should either be optional for the user or clearly justified as region-specific; neither is present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language instructions, triggers, and examples are all presented in Chinese, which effectively forces a specific language for interacting with the skill. Under the policy, this should either offer user choice or clearly document that the skill is intentionally limited to a specific locale or audience.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.