T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:78- Finding
Arbitrary readable files and API credentials can be transmitted to a configurable server
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py:78, 86-112, 189
Vulnerability Type: Unrestricted upload destination and insufficient file validation
Risk Level: HighVulnerable Code
python config.setdefault('SCNET_API_BASE', 'https://api.scnet.cn/api/llm/v1') return config def recognize_with_retry(ocr_type, file_path, config, retry_count=0): api_base = config['SCNET_API_BASE'] api_key = config['SCNET_API_KEY'] url = f"{api_base}/ocr/recognize" # Check whether the file exists if not os.path.isfile(file_path): sys.exit(f"Error: file does not exist - {file_path}") # Automatically detect the MIME type mime_type, _ = mimetypes.guess_type(file_path) if mime_type is None: mime_type = 'application/octet-stream' headers = { 'Authorization': f'Bearer {api_key}' } try: with open(file_path, 'rb') as f: files = { 'file': (os.path.basename(file_path), f, mime_type) } data = { 'ocrType': ocr_type, 'channelTag': "scnetSkills" } response = requests.post( url, headers=headers, data=data, files=files, timeout=60 )The path supplied through the command line is used directly:
python ocr_type = sys.argv[1] file_path = sys.argv[2] config = load_config() recognize_with_retry(ocr_type, file_path, config)Technical Analysis
Uploading the selected financial document to SCNet is necessary for the declared cloud OCR functionality and is explicitly disclosed in
SKILL.md. However, the implementation does not constrainSCNET_API_BASEto the documented SCNet HTTPS origin.The configured base URL is concatenated with
/ocr/recognize, after which both the bearer credenti ...[truncated 2486 chars]- Remediation
View remediation
Remediation Suggestions
- Allowlist the exact expected API scheme, hostname, port, and base path, such as
https://api.scnet.cn/api/llm/v1. - Reject non-HTTPS destinations and URLs containing embedded credentials, fragments, unexpected ports, or unapproved hostnames.
- If custom endpoints are genuinely required, make them an explicit opt-in feature and use endpoint-specific credentials rather than sending the SCNet credential to them.
- Disable redirects for authenticated upload requests, or validate every redirect destination before forwarding credentials or file content.
- Restrict accepted input to documented formats using an extension allowlist and content-signature inspection rather than relying only on
mimetypes.guess_type. - Enforce a reasonable maximum file size before opening or uploading the file.
- Resolve the supplied path and, where operationally possible, restrict access to a user-approved upload directory.
- Require explicit confirmation that identifies both the resolved file path and destination host before transmitting sensitive financial documents.
- Document retention, privacy, and regulatory implications of sending financial records to the third-party service.
- Add automated tests confirming rejection of attacker-controlled origins, plaintext HTTP endpoints, redirects to other origins, unsupported file types, and oversized files.
- Allowlist the exact expected API scheme, hostname, port, and base path, such as
