T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/main.py:76
- Finding
- Configurable API endpoint can disclose bank-card images and API credentials## Vulnerability Details **File Location**: `scripts/main.py:76-110` **Vulnerability Type**: Unrestricted sensitive-data transmission endpoint **Risk Level**: High ### Vulnerable 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 Skill must transmit a bank-card image to a remote OCR service to perform its declared function, and this transmission is disclosed in `SKILL.md`. However, the destination is taken directly from the configurable `SCNET_API_BASE` value without validating its scheme or hostname. The resulting request contains two sensitive assets: - The Scnet API credential in the `Authorization` header. - The complete user-selected file in a multipart upload. If the configuration contains an attacker-controlled URL, the script sends those assets to that server. It also permits a plaintext `http://` base URL, which could expose the request ...[truncated 1331 chars]
- Remediation
- ## Remediation Suggestions 1. Remove endpoint configurability if custom deployments are not required, and use the documented constant: ```python API_URL = "https://api.scnet.cn/api/llm/v1/ocr/recognize" ``` 2. If configurability is required, parse the URL with `urllib.parse.urlparse` and enforce: - Scheme exactly equal to `https`. - Hostname exactly equal to `api.scnet.cn`, or an explicit administrator-maintained allowlist. - An expected port and path prefix. - No embedded username or password. 3. Reject malformed URLs, plaintext HTTP endpoints, IP literals, loopback addresses, and unapproved internal or external hosts. 4. Disable redirects with `allow_redirects=False` unless they are required by the documented API. If redirects are required, validate every redirect destination before resending sensitive content. 5. Display the validated destination and obtain explicit user consent before uploading a bank-card image. 6. Use a narrowly scoped API token and support token revocation and rotation in case configuration tampering is detected.
