T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:51- Finding
Unrestricted OCR API Endpoint Can Exfiltrate Sensitive Documents and API Credentials
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py, lines 51-59 and 78-112
Vulnerability Type: Unvalidated configurable network destination
Risk Level: HighVulnerable Code
python with open(ENV_FILE, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if not line or line.startswith('#'): continue if '=' in line: key, value = line.split('=', 1) key = key.strip() value = value.strip().strip('"').strip("'") config[key] = valuepython config.setdefault('SCNET_API_BASE', 'https://api.scnet.cn/api/llm/v1') return configpython 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"错误: 文件不存在 - {file_path}") # 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 )Technical Analysis
The
SCNET_API_BASEvalue is loaded verbatim fromconfig/.envand used to construct the upload destination. The implementation does not parse or validate the URL, require HTTPS, or verify that its hostname is exactlyapi.scnet.cn.This behavior conflicts with the declared network permission in
skill.yaml, which restricts network requests toapi.scnet.cn. At runtime, however, ...[truncated 2129 chars]- Remediation
View remediation
Remediation Suggestions
- Remove
SCNET_API_BASEconfigurability if alternate service endpoints are not operationally necessary. - If configurability is required, parse the endpoint with a standard URL parser and enforce all of the following:
- The scheme must be exactly
https. - The hostname must be exactly
api.scnet.cn. - User-information components must be absent.
- Unexpected ports must be rejected.
- IP literals, redirects to other hosts, and suffix-confusion domains must be rejected.
- The scheme must be exactly
- Construct the endpoint from a trusted constant rather than concatenating an arbitrary base URL.
- Disable or explicitly validate redirects so a trusted initial endpoint cannot redirect a credential-bearing upload to another host.
- Keep the runtime network policy aligned with the
api.scnet.cnhost restriction declared inskill.yaml. - Add automated tests covering malicious values such as HTTP URLs, attacker domains, embedded credentials, unexpected ports, IP addresses, and deceptive subdomains.
- Document credential rotation procedures because any API key used while a malicious endpoint was configured must be treated as compromised.
- Remove
