Back to skill

Security audit

form2api

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent form-automation purpose, but it captures and stores authenticated browser traffic and cookies too broadly for users to install without review.

Install only if you understand that it can capture authenticated form traffic, API responses, and live browser cookies. Use it only on systems you own or are authorized to test, avoid sensitive accounts, clear the /tmp outputs afterward, and treat generated docs and cookie values as secrets.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/extract_cookies.py:121
Finding
Authentication Cookies Are Extracted, Printed, and Cached in Plaintext<![CDATA[ ## Vulnerability Details **File Location**: `scripts/extract_cookies.py:25-31`, `scripts/extract_cookies.py:82-94`, and `scripts/extract_cookies.py:121-129` **Vulnerability Type**: Plaintext storage and disclosure of authentication credentials **Risk Level**: High ### Vulnerable Code ```python CACHE_DIR = "/tmp/form_api_cookies" CACHE_MAX_AGE = 3600 # 1 hour expiration def get_cache_path(domain: str) -> str: os.makedirs(CACHE_DIR, exist_ok=True) domain_hash = hashlib.md5(domain.encode()).hexdigest()[:8] safe_domain = domain.replace(".", "_").replace(":", "_") return os.path.join(CACHE_DIR, f"{safe_domain}_{domain_hash}.txt") ``` ```python ws.send(json.dumps({ "id": 1, "method": "Network.getCookies", "params": {"urls": [target_url]} })) result = json.loads(ws.recv()) ws.close() cookies = result.get("result", {}).get("cookies", []) if not cookies: print(f"WARNING: No cookies found for {target_url}", file=sys.stderr) return "" cookie_str = "; ".join([f"{c['name']}={c['value']}" for c in cookies]) return cookie_str ``` ```python if cookie_str: with open(cache_path, "w") as f: f.write(cookie_str) print(f"# Saved to: {cache_path}", file=sys.stderr) print(cookie_str) else: print("ERROR: Failed to extract cookies", file=sys.stderr) sys.exit(1) ``` ### Technical Analysis The script uses Chrome DevTools Protocol `Network.getCookies` to retrieve browser cookies for the target URL. This interface may return sensitive session cookies, including HttpOnly cookies that normal page JavaScript cannot access. The resulting cookie string is: 1. Written unencrypted to a predictable directory under `/tmp`. 2. Created without explicitly enforcing owner-only permissions such as mode `0600`. 3. Retained for up to one hour. 4. Printed directly to standard output, where it may be captured by shell history-adjacent tooling, agent transcripts, CI logs, parent processes, or generated command output. The ...[truncated 1764 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Avoid persistent cookie caching unless it is strictly necessary. - Require explicit user confirmation immediately before extracting browser cookies. - Do not print raw cookie values to standard output. Pass credentials through a protected in-memory mechanism or directly into the authorized request process. - If temporary storage is unavoidable: - Create a private per-user directory with mode `0700`. - Create files atomically and exclusively with mode `0600`. - Use `tempfile` or an equivalent secure temporary-file API. - Reject symlinks and verify file ownership before reading or writing. - Delete the credential file immediately after use rather than retaining it for one hour. - Never include live cookie values in generated API documentation, logs, transcripts, or error messages. - Prefer narrowly scoped, short-lived API tokens over full browser session cookies where the target system supports them. - Document that CDP can expose HttpOnly session credentials and ensure the debugging endpoint is accessible only to the intended local user. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/inject_interceptor.js:32
Finding
Interceptor Indiscriminately Captures Sensitive Request and Response Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/inject_interceptor.js:32-54` and `scripts/inject_interceptor.js:72-89` **Vulnerability Type**: Excessive collection and in-page exposure of sensitive network data **Risk Level**: High ### Vulnerable Code ```javascript const result = await origFetch.apply(this, args); const clone = result.clone(); let responseBody = ''; try { responseBody = await clone.text(); } catch (e) {} window.__capturedRequests.push({ type: 'fetch', url, method, requestHeaders, requestBody, responseStatus: result.status, responseBody, timestamp: Date.now() }); return result; ``` ```javascript XMLHttpRequest.prototype.send = function (body) { const self = this; this.addEventListener('loadend', function () { window.__capturedRequests.push({ type: 'xhr', url: self.__xhrUrl || '', method: self.__xhrMethod || 'GET', requestHeaders: self.__xhrHeaders || {}, requestBody: body || null, responseStatus: self.status, responseBody: self.responseText || '', timestamp: Date.now() }); }); return origSend.apply(this, arguments); }; ``` ### Technical Analysis The interceptor hooks every page-level `fetch` and `XMLHttpRequest` call after injection. It does not restrict collection to the target form endpoint, same-origin requests, a selected HTTP method, or a short submission window. For matching requests, it retains request headers, request bodies, full response bodies, URLs, and status information in the globally accessible `window.__capturedRequests` array. These values may contain passwords, bearer tokens, CSRF tokens, personal information, business records, or other sensitive application data unrelated to the form being reverse engineered. Because the capture buffer is attached to `window`, any script executing in the same page context may read it. The workflow also instructs the agent to serialize the entire buffer, increasing the chance that unrelated ...[truncated 1345 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require the user or agent to select an expected origin, endpoint pattern, and HTTP method before capture begins. - Default to same-origin capture and reject unrelated hosts. - Capture only during a short, explicit submission window and automatically disable and restore the original APIs afterward. - Apply denylist-based redaction for fields and headers such as: - `Authorization` - `Cookie` and `Set-Cookie` - Password and passcode fields - Session, token, secret, signature, and CSRF fields - Prefer an allowlist of required form fields over storing complete request and response objects. - Do not retain full response bodies unless explicitly required; impose strict size and content-type limits. - Keep capture state in a closure rather than a public `window` property. Expose only a sanitizing export function. - Clear sensitive buffers immediately after analysis. - Display a clear warning and obtain explicit consent before capturing authenticated traffic. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/analyze_requests.py:279
Finding
Captured Network Data Is Written to Predictable Shared Temporary Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/analyze_requests.py:279-282` and `SKILL.md:48-54` **Vulnerability Type**: Unsafe temporary-file handling of sensitive data **Risk Level**: Medium ### Vulnerable Code ```python # Also output structured JSON to a file for subsequent documentation generation output_file = "/tmp/form_api_analysis.json" with open(output_file, "w") as f: json.dump(candidates, f, ensure_ascii=False, indent=2) print(f"\nStructured result saved to: {output_file}", file=sys.stderr) ``` The documented workflow also specifies a fixed raw-capture path: ```markdown Save the result to `/tmp/form_api_raw.json`. ### Step 4: Analyze requests ```bash python3 <skill_dir>/scripts/analyze_requests.py /tmp/form_api_raw.json ``` ``` ### Technical Analysis Captured traffic and analyzed request objects are stored under fixed, predictable paths in `/tmp`. The structured candidate objects retain the original captured request data, including request headers, request bodies, and response bodies. The files are opened without explicit owner-only permissions, exclusive creation, symlink protection, per-user isolation, or cleanup. On multi-user or weakly isolated systems, another local actor may be able to read the results if permissions permit. A pre-created symbolic link or manipulated path may also redirect writes where operating-system permissions allow it. Even where the system umask prevents cross-user reads, fixed files permit collisions between concurrent runs and leave sensitive data behind after the Skill finishes. ### Attack Path 1. A local attacker predicts the fixed paths `/tmp/form_api_raw.json` and `/tmp/form_api_analysis.json`. 2. A victim runs the Skill against an authenticated application. 3. Raw or analyzed traffic containing tokens, form values, or protected responses is written to those paths. 4. The attacker reads the files if runtime permissions allow access, or exploits a pre-positioned filesystem object where ...[truncated 750 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace fixed `/tmp` filenames with securely generated per-run files using `tempfile`. - Create a private per-user or per-run directory with mode `0700`. - Create output files atomically with exclusive creation and mode `0600`. - Verify that files are regular files owned by the current user and reject symbolic links. - Store only redacted analysis results; remove original headers, credentials, and unnecessary response content before serialization. - Delete raw and analyzed files immediately after documentation generation. - Add robust cleanup through `try/finally`, signal handlers, or a scoped temporary-directory context. - Avoid concurrent-run collisions by using cryptographically random filenames. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/extract_cookies.py:43
Finding
Unpinned Third-Party Dependency Installation Is Recommended<![CDATA[ ## Vulnerability Details **File Location**: `scripts/extract_cookies.py:43-47` **Vulnerability Type**: Unpinned and unverifiable dependency installation guidance **Risk Level**: Low ### Vulnerable Code ```python try: import websocket except ImportError: print("ERROR: websocket-client not installed. Run: pip3 install websocket-client", file=sys.stderr) sys.exit(1) ``` ### Technical Analysis When the `websocket` module is unavailable, the script instructs users to install `websocket-client` without a pinned version, hash verification, lockfile, or explicitly trusted package index. The named package is not shown to be malicious, and the script does not automatically execute the installation. Nevertheless, following the command resolves whatever version the configured package index currently serves. This weakens reproducibility and exposes users to compromised future releases, unsafe dependency updates, or malicious packages served through a misconfigured or attacker-controlled index. ### Attack Path 1. The script encounters a missing `websocket` module and displays the installation instruction. 2. The user runs `pip3 install websocket-client`. 3. The user's package resolver connects to its configured index or mirror. 4. A compromised release, malicious mirror, or attacker-controlled package source supplies an unsafe package version. 5. Package installation or later import executes attacker-controlled package code with the privileges of the user running the command. ### Impact Assessment A compromised dependency could execute arbitrary Python code with the installing user's privileges. This could expose browser debugging data, local files, environment variables, and authentication cookies accessible to the Skill. The current repository contains no evidence that `websocket-client` itself is malicious, and installation is manual rather than automatic. The finding therefore concerns supply-chain hardening rather than a confirmed malicio ...[truncated 18 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Declare dependencies in a reviewed requirements or lock file. - Pin `websocket-client` to a tested exact version. - Use hash verification, such as `pip install --require-hashes -r requirements.txt`. - Install only from an explicitly approved package index over TLS. - Review dependency updates before changing the pinned version. - Prefer a dedicated virtual environment rather than modifying the global Python environment. - Document the expected package name and version so users do not install an unrelated module named `websocket`. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (12)

Missing User Warnings

High
Confidence
97% confidence
Finding
The skill describes capturing real API requests from a logged-in session and later extracting cookies, but it does not warn the user that this may expose session cookies, CSRF tokens, authorization headers, and other sensitive authenticated data. In this context, that omission is especially dangerous because the skill's stated purpose is to transform intercepted authenticated traffic into reusable automation artifacts, which can facilitate replay, privilege misuse, or credential leakage if mishandled.

Missing User Warnings

High
Confidence
98% confidence
Finding
This script injects a page-level interceptor that hooks both fetch and XMLHttpRequest, then stores full request headers, request bodies, and full response bodies for every captured network call. In skill context, that can expose authentication tokens, session identifiers, PII, CSRF tokens, and sensitive API responses without any user disclosure, minimization, or access control, making the interception capability intrinsically dangerous.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger list is excessively broad and includes generic phrases like automation, scraping, and API discovery, which can cause the skill to activate for benign requests outside its intended scope. In this skill's context, overbroad activation is more dangerous because execution leads directly to interception of authenticated browser traffic and later cookie extraction, increasing the chance of unintended sensitive-data capture.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The invocation instructions do not define sufficient gating conditions before executing sensitive steps, such as confirming authorization, ownership, or awareness that authenticated requests will be captured. Given this skill injects a network interceptor and processes session-bound traffic, ambiguous activation boundaries materially raise the risk of misuse against third-party or internal systems without informed consent.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This markdown file instructs users to extract browser cookies, cache them under /tmp, and send them in curl requests, which affects authentication and sensitive session data. While the examples show how to perform the action, they do not warn users about the privacy/security implications of exposing or reusing cookies.

External Transmission

Medium
Category
Data Exfiltration
Content
## 调用示例

### curl

```bash
COOKIE=$(python3 <skill_dir>/scripts/extract_cookies.py {{target_url}})
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The sample code uses subprocess to retrieve cookies and then sends them in a requests call, transmitting session credentials to the target endpoint. The surrounding markdown does not disclose the security impact of sending authenticated requests or caution users to verify the endpoint and authorization context.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script writes filtered request data, including request bodies and response previews, to a fixed world-discoverable path under /tmp without asking the user or minimizing sensitive content. In a multi-user or shared environment, this can expose authentication tokens, personal data, or business payloads to other local processes or users, and the fixed filename also increases the chance of accidental overwrite or unintended reuse.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
This script actively extracts browser cookies via Chrome DevTools Protocol and caches them in /tmp, which can expose live session tokens and enable account or API session hijacking if another local process or user can read the file. The risk is increased because the behavior is automated, the cache location is predictable, and there is no explicit consent flow, warning, permission check, or restrictive file-mode handling for the stored secrets.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The natural-language documentation and status messaging in this file are written in Chinese, but the file does not indicate that the skill is region-specific or offer any language choice. Under the stated policy, forcing a specific language without user opt-in can be a locale-policy violation.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
The module docstring presents the tool description and usage entirely in Chinese, which imposes a specific language choice in the user-facing text. There is no indication that the user can select a different language or that the locale restriction is intentionally limited to a region-specific use case.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The file's docstring and inline user-facing instructions are entirely in Chinese, which imposes a specific language on users without any opt-in or alternative. The policy requires avoiding forced language or locale constraints unless the skill offers a choice or clearly justifies the restriction.

Static analysis

No suspicious patterns detected.