Back to skill

Security audit

HTTP Security Headers

Security checks for vulnerabilities and agentic risk

Overview

This is a legitimate security-header scanner, but it needs Review because it can make unrestricted HTTP requests from the agent’s network to internal or private targets.

Install only if you intend to let the agent make outbound HTTP HEAD requests for security-header checks. Use it only on domains you own or are authorized to test, and avoid localhost, private/internal IP ranges, cloud metadata addresses, URLs with credentials or tokens, and untrusted redirecting URLs unless you specifically accept that network exposure.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/scan_headers.py:201
Finding
Unrestricted URL Fetching Enables SSRF and Internal Network Reconnaissance## Vulnerability Details **File Location**: `scripts/scan_headers.py`, lines 201–211; user-controlled URL input is accepted at lines 581 and 592 **Vulnerability Type**: Server-Side Request Forgery (SSRF) through insufficient URL and destination validation **Risk Level**: High ### Vulnerable Code ```python def fetch_headers(url, timeout=10): """Fetch HTTP response headers from a URL.""" if not url.startswith(("http://", "https://")): url = "https://" + url ctx = ssl.create_default_context() req = Request(url, method="HEAD") req.add_header("User-Agent", "SecurityHeadersScanner/1.0") try: resp = urlopen(req, timeout=timeout, context=ctx) ``` The destination comes directly from a command-line argument: ```python parser.add_argument("urls", nargs="+", help="URL(s) to scan") ``` ```python for url in args.urls: results.append(scan_url(url)) ``` ### Technical Analysis Outbound HTTP access is necessary for the declared security-header scanning functionality. However, the implementation only tests whether the supplied string begins with `http://` or `https://`. It does not: - Parse and validate the destination hostname. - Reject loopback, private, link-local, unspecified, reserved, or multicast IP addresses. - Restrict destination ports. - Reject URLs containing embedded user credentials. - Resolve hostnames and validate every resulting address. - Revalidate destinations reached through HTTP redirects. - Protect against DNS rebinding or resolution changes between validation and connection. `urllib.request.urlopen` uses redirect handling by default. Consequently, an initially public URL may redirect the request to an internal or link-local destination without another security check. The request uses `HEAD`, which reduces response-body exposure but does not eliminate the vulnerability. Response status codes, headers, errors, and timing can reveal the ...[truncated 2041 chars]
Remediation
## Remediation Suggestions 1. Parse each URL with `urllib.parse.urlsplit` and allow only explicitly supported `http` and `https` schemes. 2. Reject malformed URLs, embedded user information, missing hostnames, ambiguous numeric IP representations, and unsupported ports. 3. Resolve the hostname before connecting and inspect every returned address with Python's `ipaddress` module. 4. Reject loopback, private, link-local, unspecified, reserved, and multicast destinations for both IPv4 and IPv6. 5. Disable automatic redirects or implement a redirect handler that repeats full URL parsing, DNS resolution, address validation, and port validation for every redirect target. 6. Mitigate DNS rebinding by connecting to the validated resolved address while preserving the original hostname for TLS certificate verification and the HTTP `Host` header. 7. Restrict destination ports to an explicit allowlist, normally ports 80 and 443, unless broader access is required and authorized. 8. Prefer an explicit public-domain allowlist when the deployment context permits it. 9. Apply outbound firewall or proxy controls as defense in depth to deny access to internal, loopback, and link-local address ranges. 10. Document that URLs containing credentials, access tokens, session identifiers, or sensitive query parameters must not be scanned. 11. Add automated tests covering direct private IPs, IPv6 loopback, alternate IP encodings, DNS names resolving to private addresses, redirects to internal addresses, and DNS-rebinding scenarios.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill instructs the agent to run a network-capable script against arbitrary user-supplied URLs, but it declares no explicit tool scope or permission boundaries. This creates an authorization gap where network access is implied by the skill content rather than constrained by metadata, increasing the risk of unintended outbound requests, misuse for scanning internal services, or SSRF-like behavior if an agent executes it automatically.

Missing User Warnings

Low
Confidence
80% confidence
Finding
This code issues network requests to user-supplied URLs using urlopen, which transmits request metadata such as the target URL and a custom User-Agent. Although the script's purpose is to scan URLs, there is no runtime disclosure, prompt, or explicit warning in the code comments/docstring that network connections will be made to the provided targets.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/scan_headers.py:297