T09 · Insecure Skill Coding Practices
- Location
scripts/epaiclt.py:9- Finding
Configurable Insecure Transport Can Expose API Credentials and Uploaded Documents
- Content
View full analysis
Vulnerability Details
File Location:
scripts/epaiclt.py, lines 9-12, 18-21, and 34-89
Vulnerability Type: Unrestricted API endpoint and optional TLS certificate verification
Risk Level: MediumVulnerable Code
python API_BASE = os.getenv("EPAI_API_BASE") API_KEY = os.getenv("EPAI_API_KEY") ACCOUNT = os.getenv("EPAI_ACCOUNT") VERIFY_TLS = os.getenv("EPAI_VERIFY_TLS", "true").lower() == "true"python HEADERS = { "Authorization": API_KEY, "Account": ACCOUNT }All HTTP operations construct their destination from the unrestricted
API_BASEvalue and use the configurable TLS verification setting. Representative credentialed requests include:python def kb_list(): url = f"{API_BASE}/knowledge/list" r = requests.get(url, headers=HEADERS, verify=VERIFY_TLS, timeout=TIMEOUT) print(json.dumps(r.json(), ensure_ascii=False, indent=2))File uploads transmit both credentials and local file contents using the same settings:
python def document_upload(kb_id, files): files = check_file_exists(files) if not files: print("❌ 没有有效文件可上传") return url = f"{API_BASE}/document/upload" parser_config = json.dumps({"lang_detect_enable": False,"backend": "pipeline-high-acc","chunk_type": "general","chunk_num": 256,"parent_chunk_num": 1024,"embed_model": "bge-m3","use_vision": True,"layout": True}) data = {"parser_config": parser_config,"parse": "true","kb_id": kb_id} upload_files = [("files", (os.path.basename(f), open(f, "rb"))) for f in files] r = requests.post(url, headers=HEADERS, data=data, files=upload_files, verify=VERIFY_TLS, timeout=TIMEOUT) print(json.dumps(r.json(), ensure_ascii=False, indent=2))Technical Analysis
EPAI_API_BASEis accepted without validating its scheme or hostname. The program therefore permits credentialed requests to plain HTTP endpoints or arbitrary hosts ...[truncated 2074 chars]- Remediation
View remediation
Remediation Suggestions
- Parse
EPAI_API_BASEwith a standard URL parser and reject every scheme excepthttps. - Validate the destination hostname against an explicit allowlist of approved EPAI service domains.
- Keep certificate verification mandatory in production and do not expose a general-purpose environment variable that silently disables it.
- If insecure TLS is required for local development, require an explicit development mode, emit a prominent warning, and reject non-loopback destinations.
- Reject URLs containing embedded credentials, fragments, unexpected ports, or malformed hostnames.
- Store the API key in a managed secret store and use a narrowly scoped, short-lived credential where the EPAI platform supports it.
- Avoid placing account or authentication-related data in query strings. In particular, remove the duplicate
Accountquery parameter used bycatalog_deletewhen the authenticated header is sufficient. - Add automated tests confirming that HTTP URLs, unapproved hosts, and disabled TLS verification are rejected before any credentialed request or file upload occurs.
- Parse
