T09 · Insecure Skill Coding Practices
Error
- Location
- server.py:29
- Finding
- Unauthenticated Cross-Origin Arbitrary File Write<![CDATA[ ## Vulnerability Details **File Location**: `server.py:29-37, 40-44, 54-57, 73-98` **Vulnerability Type**: Unauthenticated arbitrary file write with permissive CORS **Risk Level**: Critical ### Vulnerable Code ```python def is_path_allowed(p: Path) -> bool: """只允许写到用户家目录或 /tmp 下,避免任意路径写入。""" try: p = p.resolve() except Exception: return False home = Path.home().resolve() tmp = Path("/tmp").resolve() return any(str(p).startswith(str(root) + os.sep) for root in (home, tmp)) class Handler(http.server.BaseHTTPRequestHandler): def _cors(self): self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") self.send_header("Access-Control-Allow-Headers", "Content-Type") def do_POST(self): if self.path != "/feedback": return self._json(404, {"ok": False, "error": "not found"}) try: length = int(self.headers.get("Content-Length", 0)) raw = self.rfile.read(length).decode("utf-8") body = json.loads(raw) except Exception as e: return self._json(400, {"ok": False, "error": f"invalid json: {e}"}) inbox = body.get("inbox") payload = body.get("payload") if not inbox or not isinstance(payload, dict): return self._json( 400, {"ok": False, "error": "missing inbox or payload"} ) inbox_path = Path(inbox) if not is_path_allowed(inbox_path): return self._json( 403, {"ok": False, "error": f"path not allowed: {inbox_path}"} ) try: inbox_path.parent.mkdir(parents=True, exist_ok=True) inbox_path.write_text( json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8", ) except Exception as e: return self._json(500, {"ok": False, "error ...[truncated 2025 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Generate a cryptographically random, per-session bearer token and reject requests that do not present it. 2. Register one canonical inbox path when starting the server; do not accept a destination path from the HTTP request. 3. Require the destination basename to be exactly `.redline-inbox.json` and bind it to the active project directory. 4. Remove wildcard CORS. Prefer no CORS headers, or allow only an explicitly controlled origin. 5. Apply a strict request-size limit before reading the request body. 6. Validate payloads against a strict schema, including types, annotation count, and field-length limits. 7. Reject symlinks and use atomic file creation with restrictive permissions. 8. Stop the service after submission or after a short inactivity timeout. ]]>
