T09 · Insecure Skill Coding Practices
- Location
run_nonuse_webui.py:1766- Finding
Unauthenticated WebUI read endpoints disclose confidential legal case data and processing logs
- Content
View full analysis
bool: if not WEBUI_REQUIRE_AUTH: return True if not WEBUI_AUTH_TOKEN: return False auth = str(header_val or "").strip() if not auth.startswith("Bearer "): return False provided = auth.split(" ", 1)[1].strip() return provided == WEBUI_AUTH_TOKEN ``` The review-data loader reads a caller-selected output directory and returns case information, personal information, filesystem paths, and the complete raw summary: ```python def load_review_data(out_dir: str) -> Dict[str, object]: out_path = Path(out_dir).expanduser().resolve() summary_path = out_path / "扫描识别摘要.json" precheck_path = out_path / "pre_output_checklist.docx" xlsx_path = out_path / "nonuse_casebook_自动识别.xlsx" summary: Dict[str, object] = {} if summary_path.exists(): try: summary = json.loads(summary_path.read_text(encoding="utf-8")) except Exception as exc: WEBUI_LOGGER.exception("读取扫描识别摘要失败") audit({ "type": "exception", "step": "load_review_data", "file": str(summary_path), "error": str(exc), "traceback": traceback.format_exc(), "ok": False, "reason_code": "summary_json_parse_failed", }) summary = {} case_info_keys = [ ("case_no", "案件编号"), ("reg_no", "商标号"), ("mark_name", "商标名称"), ("class", "类别"), ("respondent", "答辩人"), ("applicant", "申请人"), ("period_start", "指定期间起"), ("period_end", "指定期间止"), ("revoked_goods_servi ...[truncated 6528 chars]- Remediation
View remediation
bool: if not self._auth_ok(): self._send_json({"ok": False, "error": "Forbidden"}, 403) return False return True ``` Call it before handling `/api/review-data`, `/api/status`, and any future endpoint that returns case or operational information. 2. Separate public health checks from protected application data. `/api/ping` may remain minimal, but it should not return configuration, path, case, or job information. 3. Constrain `out_dir` to an approved root or the active job: - Resolve both the requested path and approved root. - Verify containment using `Path.relative_to()`. - Reject paths outside that boundary. - Prefer a server-side job identifier instead of accepting arbitrary filesystem paths from clients. 4. Return only the fields required by the review page. Remove the unrestricted `"summary": summary` response and construct an explicit allowlist of non-sensitive fields. 5. Redact personal data, evidence names, command arguments, and absolute paths from logs before exposing them through `/api/status`. 6. Use constant-time token comparison, such as `hmac.compare_digest()`, rather than direct string equality. 7. Keep the default loopback-only binding. Clearly warn users that network binding exposes confidential legal material and should only occur on a trusted network. 8. Protect network deployments with TLS through a trusted reverse proxy or another authenticated encrypted channel. Bearer tokens and case data should not traverse an untrusted network over plaintext HTTP. 9. Add automated authorization tests covering: - Missing, malformed, and incorrect tokens - Every sensitive GET and POST endpoint - Path traversal and paths outside the approved output root - Redaction of logs and raw summary fields ]]>
