T09 · Insecure Skill Coding Practices
- Location
scripts/fofa_recon.py:483- Finding
FOFA Credentials Can Be Transmitted to an Arbitrary Configured Endpoint
- Content
View full analysis
tuple[str, str, str, int]: base_url = get_env("FOFA_BASE_URL", required=False, default="https://fofa.info").rstrip("/") email = get_env("FOFA_EMAIL") api_key = get_env("FOFA_API_KEY") timeout_raw = get_env("FOFA_TIMEOUT", required=False, default="60") try: timeout = int(timeout_raw) except ValueError: timeout = 60 return base_url, email, api_key, timeout def request_json(path: str, params: Dict[str, Any], retries: int = 3) -> Dict[str, Any]: base_url, email, api_key, timeout = api_config() merged = {"email": email, "key": api_key} merged.update(params) url = f"{base_url}{path}?{urllib.parse.urlencode(merged)}" headers = {"User-Agent": "fofamap-skill/2.0"} for attempt in range(1, retries + 1): request = urllib.request.Request(url, headers=headers) try: with urllib.request.urlopen(request, timeout=timeout) as response: return json.loads(response.read().decode("utf-8", errors="replace")) ``` ### Technical Analysis Every FOFA API request includes `FOFA_EMAIL` and `FOFA_API_KEY` in the URL query string. The destination is controlled by the optional `FOFA_BASE_URL` environment variable, but the code does not validate its scheme, hostname, port, or relationship to FOFA. Consequently, a modified process environment can redirect credentials to any HTTP or HTTPS endpoint. Use of a plaintext `http://` endpoint is also accepted, allowing credentials to cross the network without transport encryption. Even over HTTPS, query-string credentials can be retained in reverse-proxy, web-server, monitoring, or diagnostic logs. The Skill legitimately needs to authenticate to FOFA. However, transmitting ...[truncated 1380 chars]- Remediation
View remediation
