T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:82- Finding
Unrestricted local-file upload to a configurable network endpoint
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py:50-55, 82-108
Vulnerability Type: Unrestricted sensitive-file transmission and credential exposure
Risk Level: HighVulnerable Code
python env_api_base = os.environ.get('SCNET_API_BASE') if env_api_base: config['SCNET_API_BASE'] = env_api_base # 3. 设置默认值 config.setdefault('SCNET_API_BASE', 'https://api.scnet.cn/api/llm/v1')python 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 accepts a command-line file path and verifies only that it refers to a file. It does not enforce the documented image or PDF formats, inspect file content, impose a size limit, restrict the file to an approved directory, or reject known sensitive paths. Consequently, any readable local file can be submitted to the OCR endpoint.
The destination is constructed from
SCNET_API_BASE, which can be overridden through the process environment or the local.envconfiguration. There is no URL-scheme validation, hostname allowlist, or restriction to the documented SCNet service. The request sends both the selected file and the SCNet API credential in theAuthorizationheader. An attacker who can influence the environment, configuration, or invocati ...[truncated 1885 chars]- Remediation
View remediation
Remediation Suggestions
- Allowlist the documented endpoint, such as
https://api.scnet.cn/api/llm/v1, rather than accepting an unrestricted base URL. - If custom endpoints are operationally necessary, require explicit user approval and validate the URL with a proper parser:
- Require HTTPS.
- Reject embedded credentials.
- Restrict ports and hostnames.
- Resolve and reject loopback, link-local, private, and metadata-service addresses where appropriate.
- Revalidate redirects or disable them.
- Validate
ocr_typeagainst the sole supported value,QUOTA_INVOICE. - Allow only explicitly supported file types and verify their contents using file signatures rather than relying solely on filename extensions or
mimetypes.guess_type. - Reject archives unless archive processing is essential and safely constrained.
- Enforce a conservative maximum file size before reading or uploading the file.
- Restrict file selection to user-approved input locations and reject known credential, configuration, hidden, and system paths.
- Present a clear disclosure or confirmation that the selected invoice will be transmitted to a third-party OCR service.
- Avoid sending the SCNet credential to any host other than the approved SCNet API hostname.
- Add automated tests covering custom-host rejection, cleartext URL rejection, sensitive-path rejection, unsupported file formats, and oversized files.
- Allowlist the documented endpoint, such as
