T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/check_ip.py:37
- Finding
- Incomplete scans are incorrectly reported as safe<![CDATA[ ## Vulnerability Details **File Location**: `scripts/check_ip.py:37-43`, `scripts/check_ip.py:54-56`, and `scripts/check_ip.py:129-130` **Vulnerability Type**: Fail-open error handling and misleading security result **Risk Level**: Medium ### Vulnerable Code ```python async def fetch_page(session: aiohttp.ClientSession, page_num: int, semaphore: asyncio.Semaphore): """Fetch a single page""" async with semaphore: url = BASE_URL.format(page_num) try: async with session.get(url, timeout=30) as response: if response.status == 200: return page_num, await response.text() return page_num, None except Exception as e: return page_num, f"ERROR: {e}" ``` ```python if content is None or content.startswith("ERROR:"): errors.append(f"Page {page_num}: {content or 'HTTP error'}") continue ``` ```python else: print(f"\n✅ {ip} - Not found (safe)") ``` ### Technical Analysis Failed HTTP requests and exceptions are recorded in an internal `errors` list, but the normal human-readable result does not consider that list when determining whether an address is safe. The code reports `Not found (safe)` whenever `found_pages` is empty, even if some or all 3,357 pages could not be checked. Consequently, the implementation cannot distinguish between these materially different states: 1. Every page was fetched successfully and the address was not found. 2. One or more relevant pages failed to load. 3. The entire scan failed because of a network, TLS, DNS, timeout, rate-limiting, or server problem. The documentation also describes “Not found” as safe, amplifying the false assurance produced by this fail-open behavior. ### Attack Path 1. A user invokes the Skill to determine whether a target IP appears in the exposure database. 2. Requests to the watchboard are disrupted, rate-limited, blocked, ...[truncated 1126 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Introduce explicit result states such as `exposed`, `not_found`, and `inconclusive`. 2. Return `not_found` only when every expected page was retrieved and processed successfully. 3. If any page fails, prominently report the number and identity of failed pages and classify the result as incomplete or inconclusive. 4. Return a nonzero process exit code for incomplete scans so automated systems cannot treat them as successful. 5. Include error counts and a completion indicator in JSON output. 6. Add bounded retries with exponential backoff for transient HTTP failures and rate limiting. 7. Update the documentation so absence from the database is not described as proof that an endpoint is safe. 8. Add tests covering total network failure, partial page failure, HTTP error responses, and successful complete scans. ]]>
