Skip to content

Comments

Enhance security.audit tool: rate-limit retest, subdomain probe, CORS wildcard flag, and richer port info#19

Merged
Victor-Dixon merged 1 commit intomainfrom
codex/add-security-audit-tool-for-headers
Dec 31, 2025
Merged

Enhance security.audit tool: rate-limit retest, subdomain probe, CORS wildcard flag, and richer port info#19
Victor-Dixon merged 1 commit intomainfrom
codex/add-security-audit-tool-for-headers

Conversation

@Victor-Dixon
Copy link
Owner

@Victor-Dixon Victor-Dixon commented Dec 30, 2025

Motivation

  • Broaden the web security audit to be a more complete one-stop tool that surfaces rate-limiting behavior, subdomain exposure, CORS wildcard usage, and richer port/service details.
  • Provide configurable probing options so auditors can enable retesting (rate_limit_retest) and optional subdomain enumeration (subdomain_probe) without changing the core behavior.
  • Improve signal quality from HTTP responses and assets by flagging wildcard Access-Control-Allow-Origin and missing Subresource Integrity (SRI) on external assets.
  • Ensure the tool is discoverable and the repository single-source-of-truth (SSOT) is kept consistent by registering the adapter in the tool registry (tools_v2/tool_registry.lock.json).

Description

  • Added configurable options to get_spec including rate_limit_retest, retest_delay, subdomain_probe, and subdomains, and preserved the tool under 400 LOC (file is 396 lines).
  • Implemented rate-limit retesting in _check_rate_limits to optionally perform a second probe round and annotate results with `

Codex Task


Note

Introduces a compact web security auditing adapter and registers it for discovery.

  • New tools_v2/categories/security_audit_tools.py implementing SecurityAuditTool with get_spec, validation, and execution pipeline
  • Audits security headers (including CORS wildcard flag), parses HTML for external assets, flags missing SRI and untrusted CDNs
  • Optional rate-limit probing with configurable rounds, delays, and an optional retest; captures headers and 429 behavior
  • Probes common API and debug paths; extracts backend Server/X-Powered-By/Via info
  • Optional premium port scan with simple service mapping; optional subdomain enumeration via DNS resolution
  • Computes a simple risk score and findings; returns structured output
  • Registers security.audit in tools_v2/tool_registry.lock.json (also normalizes analysis.duplicates entry)

Written by Cursor Bugbot for commit a2e5fa7. Configure here.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +305 to +309
request = Request(url, headers={"User-Agent": "AgentTools-RateProbe/1.0"})
with urlopen(request, timeout=timeout) as resp:
return {"status": resp.status, "retry_after": resp.headers.get("Retry-After")}
except Exception as exc:
return {"status": "error", "error": str(exc)[:120]}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Record HTTP 429 instead of treating as error

When the target enforces rate limiting, urllib.request.urlopen raises an HTTPError for 429 responses, but this helper catches all exceptions and returns {"status": "error"}. As a result, rate_limit_triggered never becomes true even when the server is actively throttling, so the new retest logic yields false negatives in real rate-limited environments. Consider catching HTTPError separately and using its status code (e.g., exc.code) so 429s are surfaced.

Useful? React with 👍 / 👎.

Comment on lines +327 to +329
except Exception as exc:
results.append({"path": path, "status": "error", "error": str(exc)[:120]})
return [r for r in results if r.get("status") not in (404, "error")]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Endpoint probe drops valid 401/403 responses

urlopen raises HTTPError for any 4xx/5xx response, so protected endpoints that return 401/403 (common for admin/debug routes) are stored as status: "error" and then filtered out. This means existing endpoints are silently ignored unless they return 2xx, yielding false negatives for exposed paths that require auth. Handling HTTPError by capturing the status code (and not filtering it out) would preserve those findings.

Useful? React with 👍 / 👎.

results.append({"subdomain": fqdn, "resolved": True})
except Exception:
continue
return {"status": "completed", "subdomains": results}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subdomain probe creates invalid FQDNs for subdomained hosts

The _probe_subdomains method constructs FQDNs by prepending subdomain prefixes to base_host, but base_host is extracted directly from the URL's hostname which may already include a subdomain. For example, if the target URL is https://www.example.com/, base_host will be www.example.com, and the probe will try to resolve api.www.example.com instead of api.example.com. This makes the subdomain enumeration feature produce incorrect DNS lookups and miss legitimate subdomains.

Additional Locations (1)

Fix in Cursor Fix in Web

for header, data in header_results.items():
if not data["present"]:
score -= 5
findings.append(f"Missing {header} header")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CORS scoring logic penalizes secure sites, ignores wildcards

The access-control-allow-origin header is incorrectly treated as a "required" security header, causing _score_findings to penalize sites that don't set it. However, a missing CORS header is actually the secure default (same-origin policy applies), while a wildcard value * is the actual security risk. The code computes a wildcard flag but never uses it in scoring. This inverts the security logic: secure configurations get penalized while insecure wildcard CORS configurations receive no penalty.

Additional Locations (1)

Fix in Cursor Fix in Web

@Victor-Dixon Victor-Dixon merged commit a22683b into main Dec 31, 2025
1 of 2 checks passed
@Victor-Dixon Victor-Dixon deleted the codex/add-security-audit-tool-for-headers branch December 31, 2025 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant