Back to skill

Security audit

Convert to PDF

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its document-to-PDF purpose, but it deserves review because it uploads documents and an API key to a remote service and the helper script can be redirected to an arbitrary URL.

Review this before installing. Use it only for documents you are allowed to send to Cross-Service-Solutions, protect the API key, avoid passing the key in shell history, and do not set SOLUTIONS_BASE_URL or --base-url unless you fully trust and control the destination. Sensitive, regulated, or confidential files should not be converted with this skill without approval and a clear understanding of the provider's retention and privacy terms.

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/convert-to-pdf.py:46
Finding

Unrestricted Base URL Override Can Disclose Documents and API Credentials

Content
View full analysis
Dict[str, Any]: url = base_url.rstrip("/") + CREATE_PATH headers = make_headers(api_key) # multipart/form-data with multiple files under the SAME key: "files" files: List[Tuple[str, Tuple[str, Any, str]]] = [] opened = [] # We don't enforce input mime types; use octet-stream for broad compatibility. try: for p in file_paths: f = open(p, "rb") opened.append(f) files.append(("files", (os.path.basename(p), f, "application/octet-stream"))) resp = requests.post(url, headers=headers, files=files, timeout=timeout_s) ``` ```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) ``` ```python ap.add_argument( "--base-url", default=os.getenv("SOLUTIONS_BASE_URL", DEFAULT_BASE_URL), help="Base URL override", ) ``` ### Technical Analysis The conversion workflow legitimately requires transmitting selected documents and a Bearer API key to the documented Solutions API. However, the destination is configurable through both the `--base-url` command-line argument and the `SOLUTIONS_BASE_URL` environment variable. The supplied URL is used without validation of its scheme, hostname, port, or relationship to the expected API domain. Consequently, it may reference: - An attacker-controlled HTTPS server. - A plaintext HTTP endpoint, exposing data to network interception. - An unexpected internal service reachable from ...[truncated 2436 chars]
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
94% confidence
Finding

The script makes outbound network requests to a third-party service but the network capability is not covered by declared permissions. In an agent environment this is dangerous because it enables data exfiltration or remote interaction without an explicit permission boundary, especially since the skill uploads user-provided local files.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The script makes outbound network requests to a third-party service but the network capability is not covered by declared permissions. In an agent environment this is dangerous because it enables data exfiltration or remote interaction without an explicit permission boundary, especially since the skill uploads user-provided local files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README explicitly instructs users to upload documents to a third-party service but does not clearly warn that potentially sensitive user files will leave the local environment and be transmitted to an external provider. In a file-conversion skill, users may reasonably supply confidential business documents, so omission of an explicit third-party data handling warning creates a meaningful privacy and data-governance risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This endpoint documents that user-supplied files are sent to an external domain for processing, which is a real external data transmission path. In the context of document conversion, this is expected functionality, but it remains security-relevant because the transferred content may contain sensitive data and the README does not provide strong disclosure or usage constraints.

Content

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

md
## How it works
1) Upload files to:
   `POST https://api.xss-cross-service-solutions.com/solutions/solutions/api/31`
2) Poll:
   `GET  https://api.xss-cross-service-solutions.com/solutions/solutions/api/<job_id>`
3) Return `output.files[].path` as download URL(s)

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The polling endpoint confirms ongoing interaction with the same external service and therefore reinforces that document metadata and job identifiers are exchanged with a third party. While necessary for the skill's operation, this still represents a genuine data-flow risk because users may not appreciate that processing status and output retrieval are tied to an outside service.

Content

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

md
1) Upload files to:
   `POST https://api.xss-cross-service-solutions.com/solutions/solutions/api/31`
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)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill uploads user-provided documents to an external third-party API, but the user-facing description does not clearly warn about that data transfer at the point of use. This can cause users to unknowingly send sensitive documents outside the local environment or trusted platform boundary, creating confidentiality and compliance risks.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The skill is explicitly designed to transmit documents to an external service endpoint, which creates real data exposure risk because file contents leave the agent's environment and are handled by a third party. In this document-processing context, that behavior is expected, but it is still security-relevant and dangerous if users assume files are processed locally or do not understand the trust boundary.

Content

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

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

Create convert job:
- `POST /api/31`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This skill's core behavior is to upload local documents to a remote conversion API, yet there is no strong user-facing warning at execution time that file contents leave the local environment. That creates a real privacy and confidentiality risk if users supply sensitive documents expecting a local conversion workflow.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The hardcoded external endpoint confirms that the skill transmits data to an outside service. External transmission is expected for this skill's purpose, but it remains security-relevant because uploaded documents and metadata are sent off-host and returned as remote download URLs.

Content

Scanner excerpt · scripts/convert-to-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/31"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified as requests>=2.32.0, which allows future versions to be installed without review and prevents reproducible builds. In a security-sensitive skill that uploads documents to an external service, this increases supply-chain risk and makes it harder to verify whether a deployed version includes security fixes or breaking changes.

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
94% confidence
Finding

Because requests is not pinned, it is impossible to determine from this manifest whether the installed version is affected by known advisories. This is more concerning in this skill's context because it handles document uploads and likely processes remote URLs/responses, so using an affected requests release could expose credentials, transport security, or request-handling weaknesses.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.