Back to skill

Security audit

Remove metadata from PDF

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says by uploading PDFs to a remote cleanup API, but its script can be redirected to any base URL and would send both PDFs and the API key there.

Install only if you are comfortable uploading the full contents of selected PDFs to Cross-Service-Solutions. Before use, remove or tightly control the base URL override, ensure the destination is the documented HTTPS host, avoid passing API keys on the command line, and do not use confidential PDFs unless the provider's retention and access policies are acceptable.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/remove-metadata-from-pdf.py:60
Finding
Unrestricted API Endpoint Override Can Exfiltrate PDF Documents and Bearer Credentials<![CDATA[ ## Vulnerability Details **File Location**: `scripts/remove-metadata-from-pdf.py:60-71` and `scripts/remove-metadata-from-pdf.py:207-212` **Vulnerability Type**: Unrestricted sensitive-data destination and credential disclosure **Risk Level**: High ### Vulnerable Code ```python def create_job( base_url: str, api_key: str, pdf_paths: List[str], timeout_s: int = 180, ) -> Dict[str, Any]: url = base_url.rstrip("/") + CREATE_PATH headers = make_headers(api_key) # multipart/form-data with multiple PDFs under the SAME key: "files" files: List[Tuple[str, Tuple[str, Any, str]]] = [] opened = [] try: for p in pdf_paths: f = open(p, "rb") opened.append(f) files.append(("files", (os.path.basename(p), f, "application/pdf"))) resp = requests.post(url, headers=headers, files=files, timeout=timeout_s) ``` The destination is obtained from an unrestricted command-line argument or environment variable: ```python ap.add_argument( "--base-url", default=os.getenv("SOLUTIONS_BASE_URL", DEFAULT_BASE_URL), help="Base URL override", ) ``` ### Technical Analysis The Skill is declared to upload PDF files to a specific Solutions API endpoint. However, its implementation permits `base_url` to be replaced with an arbitrary value through either `--base-url` or `SOLUTIONS_BASE_URL`. The selected URL is used without validating its scheme or hostname. The script subsequently transmits two sensitive assets to that destination: 1. Every user-selected PDF file, as multipart form data. 2. The Solutions API key, in the `Authorization: Bearer` header. This exceeds the minimum privileges required for the declared functionality. Production operation requires access only to the documented Solutions API host, not permission to disclose credentials and documents to an arbitrary network destination. The absence of HTTPS enforcement also permits a caller to select a plaintext HTTP e ...[truncated 1805 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the production `--base-url` option and `SOLUTIONS_BASE_URL` override. Use the documented service URL as a fixed constant. 2. If endpoint overrides are required for development or testing: - Disable them by default. - Require an explicit development-mode flag. - Reject overrides in production builds. - Restrict destinations to an allowlist of approved hostnames. 3. Parse the destination with `urllib.parse.urlparse` and require: - The `https` scheme. - The exact approved hostname. - An expected port. - No embedded username or password. 4. Validate the final URL after all path joining and normalization, immediately before every request. 5. Ensure redirects cannot forward the bearer token or upload to an unapproved host. Prefer disabling redirects for these API calls or validating every redirect destination. 6. Inform the user clearly that the selected documents will leave the local system and identify the approved destination before uploading. 7. Prefer environment-based or secure secret-store credential input over command-line API keys, because command-line arguments can be exposed through process listings and shell history. 8. Add automated tests confirming that HTTP URLs, unapproved domains, user-information URLs, and redirect attempts are rejected. 9. Revoke and rotate any API key suspected of having been used with an untrusted endpoint. ]]>
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
94% confidence
Finding
The code performs HTTP requests to a remote service using local files and an API key, yet this network capability is not covered by declared permissions. In a skill ecosystem, this undermines trust boundaries because a user may invoke the skill without understanding that local documents will be transmitted externally.

Lp1

High
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The code performs HTTP requests to a remote service using local files and an API key, yet this network capability is not covered by declared permissions. In a skill ecosystem, this undermines trust boundaries because a user may invoke the skill without understanding that local documents will be transmitted externally.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The README explicitly instructs users to upload PDF files to a third-party API but does not warn that full document contents will leave the local system. Because PDFs often contain sensitive business, legal, or personal data, this omission can mislead users into transmitting confidential material to an external service without informed consent.

External Transmission

Medium
Category
Data Exfiltration
Content
## How it works
1) Upload PDFs to:
   `POST https://api.xss-cross-service-solutions.com/solutions/solutions/api/40`
2) Poll:
   `GET  https://api.xss-cross-service-solutions.com/solutions/solutions/api/<job_id>`
3) Return `output.files[].path` as download URL(s)
Confidence
93% confidence
Finding
This endpoint shows that the skill sends user-supplied PDFs to an external domain for processing. The transmission itself may be functionally necessary, but in this skill context it is security-relevant because users may assume a metadata-cleaning operation happens locally when it actually exposes full file contents to a remote service.

External Transmission

Medium
Category
Data Exfiltration
Content
1) Upload PDFs to:
   `POST https://api.xss-cross-service-solutions.com/solutions/solutions/api/40`
2) Poll:
   `GET  https://api.xss-cross-service-solutions.com/solutions/solutions/api/<job_id>`
3) Return `output.files[].path` as download URL(s)

## Script (CLI)
Confidence
91% confidence
Finding
The polling endpoint confirms an ongoing dependency on a remote service and indicates that processing state and result retrieval are tied to that external provider. In combination with uploaded PDFs and returned download URLs, this increases the chance that sensitive data is stored or retrievable remotely beyond the user's local environment.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly sends user-supplied PDF files to a third-party service, but the description and surrounding guidance do not clearly warn the user at the point of use that their documents leave the local environment. This creates a privacy and data-handling risk because users may submit sensitive PDFs under the mistaken assumption the operation is local or first-party.

External Transmission

Medium
Category
Data Exfiltration
Content
## API endpoints
Base URL:
- `https://api.xss-cross-service-solutions.com/solutions/solutions`

Create job:
- `POST /api/40`
Confidence
90% confidence
Finding
The skill is designed to transmit documents to an external API endpoint, which is a real data egress path for potentially sensitive PDF contents. In a document-sanitization/privacy context, external transmission is especially significant because users may use this skill specifically to protect confidential files, making unnoticed off-platform upload more dangerous.

External Transmission

Medium
Category
Data Exfiltration
Content
import requests


DEFAULT_BASE_URL = "https://api.xss-cross-service-solutions.com/solutions/solutions"
CREATE_PATH = "/api/40"
Confidence
88% confidence
Finding
The code hardcodes an external API endpoint and sends uploaded PDFs there for processing. Even if intended functionality requires this, it still represents external transmission of potentially sensitive files and therefore creates confidentiality and compliance risk in contexts where users expect local-only processing.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script uploads user-supplied PDFs to a third-party API for processing, but the command-line UX does not provide a strong, explicit warning that document contents will leave the local environment. This is risky because PDFs may contain sensitive personal, legal, financial, or confidential business information, and users could mistakenly assume metadata removal happens locally.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.32.0
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. This increases supply-chain risk because a later incompatible or vulnerable release could be pulled into the skill without deliberate validation.

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
88% confidence
Finding
Because the manifest does not pin `requests` to a specific version, it is impossible to verify whether the installed release includes fixes for known advisories affecting that package. In a skill that uploads files to a remote API and likely performs HTTP requests, uncertainty around the exact `requests` version increases the chance of exposure to network-related dependency flaws.

Static analysis

No suspicious patterns detected.