Back to skill

Security audit

Remove password from PDF

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it uploads protected PDFs, passwords, and API credentials to a remote service and allows that destination to be redirected too broadly.

Review this skill carefully before installing. Use it only for PDFs you are allowed to upload to the named third-party service, avoid confidential documents unless the provider's retention and security terms are acceptable, keep the API key in a protected environment variable, and do not use --base-url unless it is restricted to a trusted HTTPS endpoint.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/remove-password-from-pdf.py:57
Finding

Unrestricted Base URL Override Can Redirect Sensitive Documents and Credentials

Content
View full analysis
Dict[str, Any]: url = base_url.rstrip("/") + CREATE_PATH headers = make_headers(api_key) with open(pdf_path, "rb") as f: files = {"file": (os.path.basename(pdf_path), f, "application/pdf")} data = {"password": password} resp = requests.post(url, headers=headers, files=files, data=data, timeout=timeout_s) ``` The destination can be overridden through either a command-line argument or an environment variable: ```python ap.add_argument( "--base-url", default=os.getenv("SOLUTIONS_BASE_URL", DEFAULT_BASE_URL), help="Base URL override", ) ``` Polling requests subsequently send the same Bearer credential to the selected destination: ```python def get_job( base_url: str, api_key: str, job_id: Any, timeout_s: int = 30, ) -> Dict[str, Any]: url = base_url.rstrip("/") + f"/api/{job_id}" headers = make_headers(api_key) resp = requests.get(url, headers=headers, timeout=timeout_s) ``` ### Technical Analysis The skill's declared functionality requires transmitting the protected PDF, its current password, and an API key to the documented Solutions API. Sending these values to the default provider endpoint is therefore expected and necessary for the declared cloud-based workflow. However, the implementation allows `base_url` to be replaced without validating: - The URL scheme - The destination hostname - Whether TLS is required - Whether the destination belongs to the declared provider - Whether credentials may be sent to the selected origin As a result, `SOLUTIONS_BASE_URL` or `--base-url` can redirect the upload to an arbitrary HTTP or HTTP ...[truncated 1863 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/remove-password-from-pdf.py:190
Finding

PDF Password and API Key Can Be Exposed Through Command-Line Arguments

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (11)

Lp1

High
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill makes external network calls to a remote API while also handling sensitive inputs, yet this capability is not covered by declared permissions. In practice, undeclared network capability is dangerous because it enables covert transmission of documents, passwords, and API tokens in a context where operators may assume no such access exists.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill makes external network calls to a remote API while also handling sensitive inputs, yet this capability is not covered by declared permissions. In practice, undeclared network capability is dangerous because it enables covert transmission of documents, passwords, and API tokens in a context where operators may assume no such access exists.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README explicitly instructs users to send a password-protected PDF, the current password, and an API key to a third-party remote service, but it does not clearly warn that sensitive document contents and credentials leave the local environment. This creates a real privacy and data-handling risk because users may unknowingly transmit confidential files and secrets to an external processor.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This line documents an outbound POST request to an external domain that receives both the protected PDF and its current password. In the context of a document-unlocking skill, this transmission is functionally required, but it is still security-relevant because it exports sensitive content and secrets to a third party.

Content

Scanner excerpt · README.md (reported line 19)May include surrounding context.

md
## How it works
1) Upload PDF + current password to:
   `POST https://api.xss-cross-service-solutions.com/solutions/solutions/api/33`
2) Poll:
   `GET  https://api.xss-cross-service-solutions.com/solutions/solutions/api/<job_id>`
3) Return `output.files[0].path` as the download URL

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

This line documents polling a third-party API for job status, which confirms continued interaction with an external service and may expose metadata such as job identifiers and usage patterns. While less sensitive than the initial upload, it still expands the external data-sharing surface and reinforces that processing occurs off-box.

Content

Scanner excerpt · README.md (reported line 21)May include surrounding context.

md
1) Upload PDF + current password to:
   `POST https://api.xss-cross-service-solutions.com/solutions/solutions/api/33`
2) Poll:
   `GET  https://api.xss-cross-service-solutions.com/solutions/solutions/api/<job_id>`
3) Return `output.files[0].path` as the download URL

## Script (CLI)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill’s description does not clearly warn the user that both the uploaded PDF and its current password will be transmitted to a third-party external API. Because this skill handles highly sensitive document contents and a decryption secret, lack of explicit user-facing disclosure can mislead users into exposing confidential material to an external service they may not expect.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

This skill is explicitly designed to send a password-protected PDF and its password to an external service endpoint, which creates a real confidentiality risk if the document contains sensitive information or if the service is compromised, logs inputs, or retains data. The skill context makes this more dangerous than ordinary API use because it transmits both the protected content and the secret needed to decrypt it.

Content

Scanner excerpt · SKILL.md (reported line 43)May include surrounding context.

md
## API endpoints
Base URL:
- `https://api.xss-cross-service-solutions.com/solutions/solutions`

Create remove-password job:
- `POST /api/33`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This script uploads both the protected PDF and its current password to a third-party API, but the user-facing description and CLI behavior do not prominently warn that sensitive document contents and credentials leave the local system. That creates a real risk of unintended disclosure of confidential files, especially because users may expect a local password-removal operation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The code is hardwired to send sensitive files and passwords to an external domain, which is inherently risky in a skill that processes protected documents. The risk is amplified by the suspicious domain naming and by the fact that the skill's core function is deprotection of confidential material, making external transmission particularly sensitive in context.

Content

Scanner excerpt · scripts/remove-password-from-pdf.py (reported line 30)May include surrounding context.

python
import requests


DEFAULT_BASE_URL = "https://api.xss-cross-service-solutions.com/solutions/solutions"
CREATE_PATH = "/api/33"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified as requests>=2.32.0, which allows future, unreviewed versions to be installed and makes builds non-reproducible. In a security-sensitive skill that uploads password-protected PDFs and handles credentials, this increases supply-chain risk because behavior and security posture may change over time without explicit review.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.32.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
86% confidence
Finding

The manifest references requests without an exact pinned version, so it is not possible to verify whether the installed release avoids known advisories affecting some versions of the library. Given this skill uploads protected documents and their passwords to an external API, uncertainty around a networking library's security is more concerning because request handling, redirects, or credential exposure bugs could affect sensitive data in transit or logs.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.