Back to skill

Security audit

Merge PDF

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed PDF-merging integration, but it needs Review because an undocumented endpoint override can redirect PDFs and the API key away from the stated service.

Install only if you are comfortable sending the selected PDFs to Cross-Service-Solutions. Avoid using this for confidential, legal, financial, medical, or regulated documents unless you have approved that provider's handling terms. Review or remove the base-url override before use so the API key and PDFs cannot be redirected by arguments or environment variables.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/merge-pdf.py:194
Finding
Arbitrary Upload Destination Can Expose PDF Contents and API Credentials<![CDATA[ ## Vulnerability Details **File Location**: `scripts/merge-pdf.py`, lines 59-60, 82-85, and 194 **Vulnerability Type**: Unrestricted security-sensitive endpoint override **Risk Level**: High ### Vulnerable Code ```python url = base_url.rstrip("/") + CREATE_PATH headers = make_headers(api_key) ``` ```python resp = requests.post(url, headers=headers, files=files, timeout=timeout_s) ``` ```python url = base_url.rstrip("/") + f"/api/{job_id}" headers = make_headers(api_key) resp = requests.get(url, headers=headers, timeout=timeout_s) ``` ```python ap.add_argument( "--base-url", default=os.getenv("SOLUTIONS_BASE_URL", DEFAULT_BASE_URL), help="Base URL override" ) ``` ### Technical Analysis The command-line argument and inherited `SOLUTIONS_BASE_URL` environment variable can replace the documented Cross-Service-Solutions API endpoint. The supplied value is not checked against an approved hostname, scheme, port, or path. The program subsequently sends the bearer API key in the `Authorization` header and uploads all selected PDF contents to the resulting URL. Consequently, anyone capable of controlling the process arguments or environment can redirect these sensitive values to an arbitrary server. The implementation also does not reject plaintext `http://` destinations. The base-URL override is not necessary for the Skill's declared operation against its single documented provider and therefore exceeds the minimum network authority required for that operation. ### Attack Path 1. An attacker influences the Skill invocation or sets `SOLUTIONS_BASE_URL` in its execution environment. 2. The attacker assigns a URL under their control, such as `http://attacker.example`. 3. A user invokes the normal PDF merge workflow with valid documents and an API key. 4. `create_job()` sends the documents and `Authorization: Bearer <API_KEY>` to the attacker-controlled endpoint. 5. The attacker records the credential and PDF contents and can return a plausi ...[truncated 658 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `--base-url` option and `SOLUTIONS_BASE_URL` override if alternate service endpoints are not an explicit functional requirement. 2. If endpoint configurability is required, parse the URL and enforce: - The `https` scheme. - An exact allowlist of approved hostnames. - Approved ports only. - The expected path prefix. - No embedded username or password. 3. Reject redirects, or validate every redirect destination before following it. 4. Avoid obtaining security-sensitive network destinations from ambient environment variables. 5. Display or otherwise confirm the destination and exact input files before uploading sensitive documents. 6. Use a narrowly scoped, revocable API credential and document the provider's data retention and deletion behavior. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/merge-pdf.py:31
Finding
PDF Validation Relies Only on the Filename Extension<![CDATA[ ## Vulnerability Details **File Location**: `scripts/merge-pdf.py`, lines 31-32 and 238-250 **Vulnerability Type**: Insufficient file-type validation before remote upload **Risk Level**: Low ### Vulnerable Code ```python def is_pdf_file(path: str) -> bool: return path.lower().endswith(".pdf") ``` ```python non_pdf = [p for p in pdf_paths if not is_pdf_file(p)] if non_pdf: print(json.dumps( { "status": "error", "error": "not_a_pdf", "message": "All inputs must be .pdf files.", "files": non_pdf, }, ensure_ascii=False, indent=2 )) return 2 ``` ### Technical Analysis The implementation treats any regular file whose name ends in `.pdf` as a valid PDF. It does not inspect the PDF signature, verify structural parseability, or otherwise confirm that the content is a PDF before opening and uploading the complete file. Filename extensions are attacker-controlled metadata and provide no reliable assurance about file contents. A non-PDF file, including a sensitive file copied or linked under a `.pdf` name, can therefore pass validation and be transmitted to the third-party service as `application/pdf`. ### Attack Path 1. An attacker or untrusted caller creates or selects a non-PDF file with a `.pdf` suffix. 2. The file passes the `os.path.isfile()` and extension checks. 3. The script opens the file in binary mode. 4. The entire content is submitted to the remote merge API under the `files` multipart field. 5. The third-party service receives data that the user or operator may have expected the program to reject. ### Impact Assessment Exploitation can disclose unintended local file contents to the configured remote service. The practical scope is limited to files that the executing process can read and that are supplied as inputs, but this may still include sensitive information if paths are selected by an untrusted caller or through an automated agent workflow ...[truncated 85 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Verify the `%PDF-` file signature rather than relying exclusively on the filename. 2. Parse each input with a maintained PDF library and reject malformed or non-PDF content before upload. 3. Apply reasonable file-count and file-size limits. 4. If callers are not fully trusted, constrain readable inputs to approved directories and handle symbolic links according to an explicit policy. 5. Present the resolved paths, filenames, sizes, and remote destination for user confirmation before transmission. 6. Treat content validation as a safety check rather than a substitute for user authorization to upload the selected files. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Open-Ended Dependency Version Prevents Reproducible Installation<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt`, line 1 **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Low ### Vulnerable Code ```text requests>=2.32.0 ``` ### Technical Analysis The dependency specification accepts any current or future `requests` release at or above version 2.32.0. As a result, installations performed at different times can resolve to different, unaudited package versions. No evidence indicates that the currently named package is malicious. The security concern is that the package set is not reproducible and can silently incorporate future dependency changes without review. The requirement also lacks package hashes, leaving installation integrity dependent on the configured package index and transport controls. ### Attack Path 1. The Skill is installed or rebuilt without a lock file or exact version constraint. 2. The package resolver selects a newer release than the version originally reviewed. 3. That release or one of its transitive dependencies contains a vulnerability, compromised code, or an incompatible behavioral change. 4. The newly resolved code is imported and executes with the permissions of the Skill process. ### Impact Assessment A compromised or vulnerable dependency would run within the Skill process and inherit its ability to read the selected PDF files, access the API key, and make network requests. The finding does not establish an existing compromise; it identifies avoidable supply-chain exposure and a lack of reproducible dependency resolution. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `requests` and its transitive dependencies to reviewed, exact versions. 2. Generate and commit a lock file using an appropriate dependency-management tool. 3. Require cryptographic hashes during installation, such as with pip's `--require-hashes` mode. 4. Install packages only from a trusted package index over authenticated TLS. 5. Use automated vulnerability monitoring, but update pinned versions only through a controlled review and testing process. 6. Regenerate hashes and lock data whenever an approved dependency update is made. ]]>
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 (10)

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding
The skill uses 'env' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding
The skill uses 'network' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README explicitly instructs users to upload their PDF files to a third-party service but does not warn about privacy, retention, confidentiality, or jurisdictional handling of the uploaded documents. Because PDFs often contain sensitive business or personal data, this omission can lead users to transmit confidential information off-platform without informed consent.

External Transmission

Medium
Category
Data Exfiltration
Content
- Register / get key: https://login.cross-service-solutions.com/register

## How it works
1) Upload PDFs to `POST https://api.xss-cross-service-solutions.com/solutions/solutions/api/30`
2) Poll `GET https://api.xss-cross-service-solutions.com/solutions/solutions/api/<job_id>` until done
3) Return `output.files[0].path` as the download URL
Confidence
88% confidence
Finding
This step documents transmission of user-provided PDFs to an external domain for processing, which creates a real data-exfiltration surface by design. In the context of a file-merging skill, sending full document contents to a remote service is more dangerous than ordinary API metadata exchange because the payload itself may contain sensitive data.

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/30`
2) Poll `GET https://api.xss-cross-service-solutions.com/solutions/solutions/api/<job_id>` until done
3) Return `output.files[0].path` as the download URL

## Script (CLI)
Confidence
82% confidence
Finding
Polling the external service for job completion continues interaction with the third-party processor and confirms that user data has been handed off to an outside system. While less severe than the initial upload, it is still part of the same external-processing design and contributes to the overall privacy and trust risk.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill explicitly uploads user-provided PDF files to a third-party service, but it does not provide a clear user-facing warning about that data transfer or the associated exposure of file contents and metadata. This can lead users to unknowingly send sensitive documents outside the local agent environment, creating confidentiality and compliance risks.

External Transmission

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

Create merge job:
- `POST /api/30`
Confidence
89% confidence
Finding
The skill is designed to send files to an external API endpoint, which creates a real data exfiltration surface because complete user PDFs are transmitted off-platform. In this context the external call is functionally necessary, but it remains security-relevant because sensitive document contents may be exposed to a third party if users are not clearly informed and if the service is not properly vetted.

External Transmission

Medium
Category
Data Exfiltration
Content
import requests


DEFAULT_BASE_URL = "https://api.xss-cross-service-solutions.com/solutions/solutions"
CREATE_PATH = "/api/30"
Confidence
89% confidence
Finding
This skill uploads user-provided PDFs to an external third-party endpoint, creating a real data exfiltration and privacy risk because document contents may be sensitive. The risk is heightened by the hardcoded external service and base-url override support, which means confidential files leave the local trust boundary and could also be redirected to another endpoint if configuration is tampered with.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.32.0
Confidence
95% confidence
Finding
The dependency is specified as `requests>=2.32.0` without an upper bound or exact pin, which makes builds non-reproducible and can unintentionally pull in different versions over time. In a skill that uploads user-provided PDFs to an external service, relying on an unpinned HTTP client increases supply-chain and stability risk because future installs may include a vulnerable or behavior-changing release.

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
89% confidence
Finding
The manifest references `requests` but does not pin the exact version, so it is impossible to verify from this file alone whether installation will resolve to a release affected by known advisories. Because this skill likely handles outbound requests, uploads user files, and may interact with redirects, auth, or URL handling, an unverifiable `requests` version leaves open the possibility of inheriting known client-side security flaws depending on the environment and install time.

Static analysis

No suspicious patterns detected.