T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:78- Finding
Unrestricted OCR API Endpoint Can Exfiltrate Identity Documents and API Credentials
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py:78-112
Vulnerability Type: Arbitrary sensitive-data transmission endpoint
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): """ 带重试机制的 OCR 识别函数。 当遇到 429 (Too Many Requests) 时,自动等待后重试。 调用 Scnet OCR API 进行识别""" api_base = config['SCNET_API_BASE'] api_key = config['SCNET_API_KEY'] url = f"{api_base}/ocr/recognize" # 检查文件是否存在 if not os.path.isfile(file_path): sys.exit(f"错误: 文件不存在 - {file_path}") # 自动检测 MIME 类型 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_BASEconfiguration value is used directly to construct the upload destination. The code does not validate:- The URL scheme, allowing plaintext HTTP.
- The destination hostname.
- The destination port.
- Embedded URL credentials.
- Whether the final request destination remains the documented Scnet service.
The resulting request contains both an
Authorization: BearerAPI credential and the complete user-selected document. Household-register documents may contain names, addresses, dates of birth, identification numbers, family relationships, and other sensitive identity information.Uploading a document to t ...[truncated 2076 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove
SCNET_API_BASEconfigurability if alternate service endpoints are not operationally required. - If configurability is required, parse the URL with
urllib.parse.urlparseand enforce all of the following:- Scheme must be
https. - Hostname must be an explicit allowlisted hostname such as
api.scnet.cn. - Port must be absent or equal to
443. - Username and password URL components must be absent.
- The base path must match the expected API prefix.
- Scheme must be
- Construct the endpoint from a fixed origin and fixed path rather than concatenating an unrestricted string.
- Set
allow_redirects=False, or manually process redirects and revalidate every destination before transmitting a document or credential. - Fail closed when URL validation is unsuccessful.
- Clearly notify users that the selected document will be uploaded to the named third-party service and obtain confirmation before transmitting identity documents.
- Consider displaying the validated destination hostname before the upload without logging the bearer token or document contents.
- Add tests covering HTTP URLs, unexpected hosts, embedded credentials, alternate ports, malformed URLs, and redirects.
- Remove
