T09 · Insecure Skill Coding Practices
Error
- Location
- api/geo_api.py:21
- Finding
- Hardcoded API Key Grants Unauthorized Pro Service Access<![CDATA[ ## Vulnerability Details **File Location**: `api/geo_api.py`, lines 21-23 **Vulnerability Type**: Hardcoded authentication credential **Risk Level**: High ### Vulnerable Code ```python API_KEYS = { "pro_key_placeholder": {"tier": "pro", "brand_limit": float('inf')}, } ``` The credential is also used directly by the test client in `api/test_api.py`, lines 6-13: ```python API_URL = "http://localhost:8080/search" TEST_KEY = "pro_key_placeholder" def test_search(brand="91tokenhub"): """Test search""" resp = requests.post( API_URL, headers={"X-API-Key": TEST_KEY}, json={"brand": brand, "max_results": 5} ) ``` ### Technical Analysis The API authenticates clients by comparing the `X-API-Key` header against the static `API_KEYS` dictionary. The repository-visible value `pro_key_placeholder` is therefore an active credential rather than an inert example. Anyone with access to the source code can authenticate as a Pro user. The associated `brand_limit` is infinite, and the application does not implement effective per-key request quotas or rate limiting. If this service is exposed beyond localhost, the credential can be used by unauthorized clients to invoke searches that consume the server operator's Tavily API allowance. Static plaintext key comparison also prevents safe credential rotation, auditing, expiration, and revocation without modifying and redeploying the application. ### Attack Path 1. An attacker reads the public or otherwise accessible project source. 2. The attacker extracts `pro_key_placeholder` from `api/geo_api.py` or `api/test_api.py`. 3. The attacker identifies an exposed deployment of the Flask `/search` endpoint. 4. The attacker sends requests containing: ```http X-API-Key: pro_key_placeholder ``` 5. `verify_api_key()` accepts the credential and assigns the Pro tier. 6. Each authenticated request causes the service to invoke Tavily using the server-owned `TAVILY_API_KEY`. 7. The at ...[truncated 619 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the hardcoded credential from both production and test code. 2. Immediately rotate or revoke `pro_key_placeholder` in every deployed environment. 3. Load production credentials from a protected secret manager or deployment secret. 4. Store only cryptographic hashes of client API keys, using constant-time comparison where applicable. 5. Give test environments separate credentials that cannot authenticate to production. 6. Add credential expiration, rotation, revocation, and usage-auditing support. 7. Implement per-key rate limits, concurrency limits, and Tavily quota budgets. 8. Reject startup in production if known placeholder or example credentials are configured. 9. Add secret scanning to CI to prevent future plaintext credentials from being committed. ]]>
