fix(agent): suppress internal exception details in selfRegister error responses#259
Closed
sebastiondev wants to merge 2 commits into
Closed
fix(agent): suppress internal exception details in selfRegister error responses#259sebastiondev wants to merge 2 commits into
sebastiondev wants to merge 2 commits into
Conversation
…e (CWE-209) The /api/claw/agents/selfRegister endpoint returned str(exc) in the HTTP 500 response body, leaking database schema, table names, and internal paths to unauthenticated callers. Replace with a generic error message and log the exception server-side.
The original tests patched routes_agent.get_db_connection which is called BEFORE the try/except block (line 563), so the exception bypassed the fix's handler entirely. Patching hash_password instead (called at line 571, inside the try) exercises the actual CWE-209 fix and all 4 tests now pass.
Author
|
Closing this as inactive — no maintainer response after 14 days. The security finding and fix remain valid. If this is still relevant, I'm happy to reopen, rebase, or re-submit against a different branch. Just drop a comment. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
/api/claw/agents/selfRegisterendpoint inservice/server/routes_agent.pyreturns raw Python exception messages to HTTP clients on internal errors. When an unexpected exception occurs during agent registration, the handler at line 724 passesstr(exc)directly into theHTTPExceptiondetail field:This is an instance of CWE-209: Generation of Error Message Containing Sensitive Information. Depending on the exception type, the leaked message can include database file paths, SQLite schema details, connection strings, internal hostnames, or Python tracebacks — all useful for reconnaissance.
This endpoint is particularly sensitive because it requires no authentication. Unlike similar patterns in
routes_signals.py,routes_experiments.py,routes_challenges.py, androutes_team_missions.py(which are behind auth),selfRegisteris publicly accessible and deployed at ai4trade.ai.Proof of Concept
An attacker can trigger internal errors and read the exception details from the response. For example, if the database is temporarily unavailable or a schema migration leaves a column missing:
If any
Exceptionis raised inside the try block (lines 566–724 ofroutes_agent.py), the current code returns the raw exception string in the JSON response body:{"detail": "sqlite3.OperationalError: no such table: agents"}or:
{"detail": "OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused\n\tIs the server running on host \"internal-db.cluster.local\" ..."}This reveals database technology, internal hostnames, table names, and schema details to unauthenticated users.
Fix
The fix replaces
str(exc)with a static generic message'Agent registration failed'and logs the actual exception server-side viaprint()so developers can still diagnose issues:This preserves the existing error handling flow (connection cleanup, 500 status code) while preventing information leakage. The
HTTPExceptionre-raise for known errors (e.g., 400 for duplicate names) is unaffected — that handler is in a separateexcept HTTPExceptionblock above.Testing
The PR includes a test file (
service/server/tests/test_cwe209_agent_registration.py) with four tests:test_successful_registration_still_works— Verifies normal registration is unaffected by the fix.test_duplicate_registration_returns_409_not_internal_details— Confirms duplicate agent names still return proper 400/409 errors.test_internal_error_returns_generic_message— Patcheshash_passwordto raise aRuntimeErrorcontaining a simulated secret (SECRET_DB_CONNECTION_STRING_12345) and asserts the 500 response contains only the generic message, not the secret.test_internal_error_does_not_leak_traceback— Patcheshash_passwordto raise an exception mimicking a SQLite error and asserts no database internals (sqlite3,OperationalError,Traceback) appear in the response.All four tests pass.
Security Analysis
The vulnerability is exploitable because:
except Exceptionhandler is a catch-all covering ~160 lines of code (lines 566–724), meaning many different failure modes can produce varied and informative exception messages.detailfield directly into the JSON response body with no sanitization.Before submitting, we considered whether existing protections mitigate this. The CORS middleware is permissive (
allow_origins=CORS_ORIGINS,allow_methods=['*']), and there is no global error handler or middleware that sanitizes 500 responses. The endpoint has no rate limiting or authentication gate. The information disclosure is real and reachable from the public internet.Severity is low-to-medium: the leaked information aids reconnaissance (revealing database technology, internal network topology, table schemas) but is not directly exploitable for data theft or code execution on its own.
Note: Similar
str(exc)patterns exist in other route files (routes_signals.py,routes_experiments.py,routes_challenges.py,routes_team_missions.py), but those endpoints are behind authentication. This PR targets the single unauthenticated instance as the highest-priority fix.Submitted via the Sebastion AI GitHub App.