Back to skill

Security audit

Phy Cors Audit

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real CORS auditing skill, but it needs review because it can probe arbitrary URLs from the agent environment and includes an unsafe generated Express preflight example.

Review before installing. Use it only for endpoints you own or are authorized to test, and avoid running it against localhost, private network addresses, metadata services, or untrusted user-supplied URLs. Treat generated Express snippets cautiously and ensure preflight handling reuses the same restricted CORS policy.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:96
Finding
Unrestricted Target URL Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:96-106` **Vulnerability Type**: Unrestricted outbound request / SSRF **Risk Level**: High ### Vulnerable Code ```python def probe_cors(url: str, origin: str, method: str = 'GET') -> dict: """Send a single CORS probe and return response headers.""" result = subprocess.run( ['curl', '-sI', '-X', method, url, '-H', f'Origin: {origin}', '-H', 'Content-Type: application/json', '--max-time', '10', '--user-agent', 'CorsAuditor/1.0'], capture_output=True, text=True ) ``` ### Technical Analysis The user-controlled `url` is passed directly to `curl` without validating its scheme, hostname, port, resolved IP address, or network destination. The skill explicitly advertises support for probing any supplied URL. Using an argument array prevents conventional shell metacharacter injection, but it does not prevent server-side request forgery. An attacker can supply URLs targeting loopback interfaces, private address ranges, link-local services, cloud metadata endpoints, or internal hostnames accessible from the agent's execution environment. The code also does not explicitly restrict curl to HTTP and HTTPS protocols. Although the `-I` option limits normal HTTP probes to response headers, those headers can still disclose internal software, service availability, authentication behavior, routing information, and CORS configuration. ### Attack Path 1. An attacker persuades a user or automated agent to audit an attacker-selected target. 2. The attacker supplies an internal URL, such as a loopback address, private service hostname, or link-local metadata endpoint. 3. `probe_cors()` passes the URL directly to `curl`. 4. The request originates from the environment running the skill rather than from the attacker. 5. The internal service's status code and response headers are parsed and included in the audit result. 6. The attacker uses the results for in ...[truncated 655 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Accept only `http` and `https` URLs. - Reject URLs containing embedded credentials. - Resolve the hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 addresses. - Revalidate the destination immediately before connection to reduce DNS-rebinding risk. - Explicitly restrict curl protocols, for example with `--proto =http,https`. - Keep redirects disabled. If redirects are later enabled, validate every redirect destination using the same policy. - Apply an outbound network allowlist or egress firewall so the process cannot reach metadata services or private networks. - Require explicit user confirmation before probing a destination outside an approved domain list. - Place an option terminator before the URL and use a validated canonical URL as the final positional argument. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:493
Finding
Generated Express Preflight Handler Does Not Reuse the Restricted CORS Policy<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:493-511` **Vulnerability Type**: Inconsistent CORS configuration **Risk Level**: Medium ### Vulnerable Code ```javascript const ALLOWED_ORIGINS = new Set([{origins_list}]); app.use(cors({{ origin: (origin, callback) => {{ // Allow requests with no origin (server-to-server, curl) if (!origin || ALLOWED_ORIGINS.has(origin)) {{ callback(null, true); }} else {{ callback(new Error(`Origin ${{origin}} not allowed by CORS`)); }} }}, credentials: {str(allow_credentials).lower()}, methods: {methods}, allowedHeaders: {headers}, }})); // Always respond to preflight app.options('*', cors()); ``` The same insecure pattern is repeated in the example at `SKILL.md:694`: ```javascript app.options('*', cors()); // handle preflight ``` ### Technical Analysis The main Express middleware uses an explicit origin allowlist, but the preflight route creates a new `cors()` middleware instance without passing the restricted options. The default Express `cors` configuration is permissive and can return wildcard CORS approval for OPTIONS requests. Consequently, the generated configuration applies one policy to normal requests and a different policy to preflight requests. This does not automatically expose credentialed data in a correctly behaving browser because the default preflight handler does not enable credentials and the restricted main middleware may still reject the subsequent request. However, it creates an incorrect and unexpectedly permissive security boundary. It may widen unauthenticated cross-origin access and can become exploitable when combined with permissive route handlers, middleware ordering mistakes, custom clients, or later configuration changes. ### Attack Path 1. A developer copies the generated Express configuration and expects the allowlist to apply to all CORS processing. 2. An attacker-controlled origin submits an OPTIONS preflight request. 3. The req ...[truncated 854 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Define one CORS options object and reuse it for both normal and preflight processing: ```javascript const ALLOWED_ORIGINS = new Set([ 'https://myapp.com', 'https://staging.myapp.com', ]); const corsOptions = { origin(origin, callback) { if (!origin || ALLOWED_ORIGINS.has(origin)) { return callback(null, true); } return callback(new Error(`Origin ${origin} not allowed by CORS`)); }, credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization'], }; app.use(cors(corsOptions)); app.options('*', cors(corsOptions)); ``` Also: - Add `Vary: Origin` whenever the response varies according to the request origin. - Test both OPTIONS and actual requests from trusted and untrusted origins. - Avoid wildcard preflight handlers unless the associated resources are deliberately public and unauthenticated. - Ensure middleware ordering cannot allow OPTIONS requests to bypass the restricted policy. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
SKILL.md:436
Finding
Substring-Based Directory Exclusions Can Hide Files from Security Scanning<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:436-441` **Vulnerability Type**: Incomplete static analysis caused by unsafe path filtering **Risk Level**: Low ### Vulnerable Code ```python for ext in ['.js', '.ts', '.jsx', '.tsx', '.py', '.go', '.java', '.rb']: for fpath in glob.glob(f'{src_dir}/**/*{ext}', recursive=True): if any(skip in fpath for skip in SKIP_DIRS): continue try: content = Path(fpath).read_text(errors='replace') ``` The exclusion tokens are defined at `SKILL.md:320-321`: ```python SKIP_DIRS = {'node_modules', '.git', 'dist', 'build', '__pycache__', '.next', 'vendor', 'venv', '.venv'} ``` ### Technical Analysis The scanner determines whether to exclude a file by checking whether any exclusion token occurs anywhere in the complete path string. It does not verify that the matching value is an actual directory component. As a result, legitimate source files and directories can be omitted when their names merely contain a skip token. Examples include `src/vendor_api.py`, `src/builders/cors.ts`, or a parent path whose name contains `dist`. The scanner silently continues without recording that the file was excluded. This can produce false-negative security reports. ### Attack Path 1. Vulnerable CORS code is placed in a file or directory whose path contains an exclusion token as a substring. 2. The recursive glob discovers the file. 3. `any(skip in fpath for skip in SKIP_DIRS)` evaluates to true. 4. The scanner silently skips the file. 5. Insecure CORS patterns in that file are not reported. 6. A reviewer may incorrectly conclude that the scanned source tree contains no matching CORS vulnerabilities. ### Impact Assessment This flaw does not directly provide code execution or elevated privileges. Its impact is reduced audit coverage and false assurance. The affected scope includes any supported source file whose full path contains one of the exclusion strings, even w ...[truncated 154 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Normalize each path and compare exact directory components instead of arbitrary substrings: ```python path = Path(fpath) if any(part in SKIP_DIRS for part in path.parts[:-1]): continue ``` For stronger handling: - Resolve the scan root and ensure every candidate remains beneath that root. - Apply exclusions only to directory components, not the filename. - Record skipped paths in verbose or diagnostic output. - Add regression tests for paths such as `src/builders/app.ts`, `src/vendor_api.py`, and genuine excluded paths such as `node_modules/pkg/index.js`. - Consider using `Path.rglob()` and pruning exact excluded directories during traversal. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
allowedHeaders: {headers},
}}));

// Always respond to preflight
app.options('*', cors());''',

        'fastapi': f'''# FastAPI (pip install fastapi)
Confidence
70% confidence
Finding
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger list includes broad terms such as "preflight" and "cors policy," which are common in ordinary debugging or educational discussions and may cause the skill to activate when the user did not intend to run a live security audit. In this skill, unintended invocation matters because the tool is designed to probe live URLs and scan code, increasing the chance of unnecessary network activity or disruptive workflow behavior.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Option 1: Probe a live API endpoint
/cors-audit https://api.myapp.com/users

# Option 2: Probe with specific origin
/cors-audit https://api.myapp.com --origin https://evil.com
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Option 1: Probe a live API endpoint
/cors-audit https://api.myapp.com/users

# Option 2: Probe with specific origin
/cors-audit https://api.myapp.com --origin https://evil.com
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
CODE_PATTERNS = [

    # Express cors() with no options = allow all origins
    {
        'name': 'EXPRESS_CORS_NO_OPTIONS',
        'pattern': re.compile(r'app\.use\s*\(\s*cors\s*\(\s*\)\s*\)', re.I),
Confidence
70% confidence
Finding
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
),
    },

    # Python: CORS_ORIGINS = "*" or origins="*"
    {
        'name': 'PYTHON_CORS_WILDCARD',
        'pattern': re.compile(
Confidence
65% confidence
Finding
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Static analysis

No suspicious patterns detected.