T05 · Unauthorized Access and Privilege Escalation
Warning
- Location
- scripts/api_server.py:55
- Finding
- Unauthenticated Externally Reachable Bounty and Payment-Triggering API<![CDATA[ ## Vulnerability Details **File Location**: `scripts/api_server.py:55-77, 115-176, 204` **Vulnerability Type**: Missing authentication, authorization, rate limiting, and resource limits **Risk Level**: Medium ### Vulnerable Code ```python @self.app.route('/bounty', methods=['POST']) def post_bounty(): """ POST /bounty - Submit validation bounty Payload: { "raw_data": {...}, "schema": {...}, "validation_rules": "crypto", "amount_usdc": 5.00, "payout_address": "SOLANA_ADDR" } Response: { "status": "validated", "score": 0.87, "clean_data": {...}, "issues": [...], "payment_txn": "..." } """ return self._handle_bounty_request() ``` ```python def _handle_bounty_request(self) -> Tuple[Dict[str, Any], int]: """Handle POST /bounty request.""" try: # Parse request data = request.get_json() if not data: return jsonify({ "status": "error", "message": "Request body must be JSON" }), 400 # Validate required fields required = ["raw_data", "amount_usdc", "payout_address"] missing = [f for f in required if f not in data] if missing: return jsonify({ "status": "error", "message": f"Missing required fields: {', '.join(missing)}" }), 400 raw_data = data["raw_data"] schema = data.get("schema") rules = data.get("validation_rules", "json-strict") amount_usdc = data["amount_usdc"] payout_address = data["payout_address"] # Validate amount if not isinstance(amount_usdc, (int, float)) or amount_usdc <= 0: return jsonify({ "status": "error", "message": "amount_usdc must be a positive number" }), 400 # Validate address if not self.payment_handler._is_v ...[truncated 4737 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Restrict the default bind address** - Bind to `127.0.0.1` by default. - Require an explicit configuration option to expose the service externally. - Place externally exposed deployments behind a hardened reverse proxy and firewall. 2. **Require strong authentication** - Require API keys, signed requests, mutual TLS, or an authenticated identity provider. - Store credentials in a secret manager or protected environment variable. - Compare secrets using constant-time functions where applicable. 3. **Enforce authorization** - Verify that the authenticated caller is permitted to create bounties and request payments. - Bind each bounty to an authorized payer account and server-side budget. - Do not trust client-provided payment amounts or recipient addresses without policy validation. 4. **Separate validation from payment execution** - Make validation a non-financial operation. - Queue payment requests for a separate trusted worker. - Require a signed bounty record and successful result verification before approving a payment. - Never directly pass request-controlled values to a funded payment backend. 5. **Add financial controls** - Enforce per-request, per-user, and daily payout limits. - Require sufficient authorized escrow balance. - Add approval thresholds for high-value payments. - Use idempotency keys and reject replayed or duplicate requests. 6. **Add resource controls** - Configure Flask or the reverse proxy with a maximum request-body size. - Limit nesting depth, object count, schema size, and output size. - Add per-client and global rate limiting. - Apply request timeouts and bounded worker concurrency. - Expire or persist payment records in bounded storage rather than an unlimited list. 7. **Harden error handling** - Return generic client-facing errors such as `"Internal server error"`. - Record detailed exceptions only in protected server- ...[truncated 359 chars]
