Back to skill

Security audit

Frontend Backend Flow Test

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent API contract audit skill, but its optional live test generator can unexpectedly change data and persist credentials, so it should be reviewed before installation.

Use the static audit command only if you install this skill. Avoid scripts/generate_tests.py until the read-only delete path, credential handling, and template injection issues are fixed; do not run generated helpers against production or with real reusable credentials.

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
scripts/generate_tests.py:173
Finding
Read-only mode can generate helpers that issue DELETE requests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_tests.py:173-181`, `scripts/generate_tests.py:436-438` **Vulnerability Type**: Improper enforcement of read-only operation **Risk Level**: High ### Vulnerable Code ```python try: # CREATE total += 1 if self.test_create(): passed += 1 {test_sequence} finally: # Always try to delete (rollback) self.test_delete() ``` The generator changes the initial operation to GET in read-only mode but does not remove the unconditional deletion: ```python if read_only: create_method = 'GET' create_endpoint = feature_config.get('read', {}).get('detail_endpoint') or feature_config.get('read', {}).get('endpoint', create_endpoint) test_sequence = '' ``` The generated deletion method can issue a state-changing request: ```python if "{delete_request_encoding}" == "json": r = requests.{http_delete_method}( f"{API_BASE}{endpoint}", json=payload, headers=self.get_auth_headers(), timeout=10 ) elif "{delete_request_encoding}" == "params": r = requests.{http_delete_method}( f"{API_BASE}{endpoint}", params=payload, headers=self.get_auth_headers(), timeout=10 ) else: r = requests.{http_delete_method}( f"{API_BASE}{endpoint}", data=payload, headers=self.get_auth_headers(), timeout=10 ) ``` ### Technical Analysis The `--read-only` option does not enforce an invariant that all generated requests are non-mutating. It changes the nominal CREATE operation to GET and removes the update sequence, but `run()` still executes `self.test_delete()` in its `finally` block. If the GET response supplies a value through the configured ID extraction path, that value is assigned to `self.resource_id`. The cleanup routine then treats the retrieved resource as test-created data and sends the configured deletion request. The production-like URL confirmation also excludes ...[truncated 1370 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate no DELETE method and make no call to `test_delete()` when `read_only` is true. 2. Use separate read-only and write-capable templates rather than conditionally modifying one CRUD template. 3. Enforce a strict read-only method allowlist containing only `GET` and `HEAD`. 4. Reject configurations containing create, update, or delete operations when `--read-only` is selected. 5. Do not assign IDs returned by read operations to cleanup state. 6. Require explicit confirmation for every production-like destination, including read-only mode. 7. Add automated tests that inspect generated helpers and fail if read-only output contains `post`, `put`, `patch`, `delete`, or other mutation-capable request calls. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_tests.py:41
Finding
Test-account credentials are embedded in executable generated source files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_tests.py:41-44`, `scripts/generate_tests.py:451-452`, `scripts/generate_tests.py:473-476` **Vulnerability Type**: Plaintext sensitive-data exposure **Risk Level**: High ### Vulnerable Code The generated helper contains literal credential placeholders: ```python login_payload = { 'email': '{email}', 'password': '{password}' } ``` Values are taken directly from the configuration and inserted into the source: ```python email=test_account.get('email', 'test@example.com'), password=test_account.get('password', 'password'), ``` The resulting source is written to disk and assigned mode `0755`: ```python # Write file output_file = output_dir / f"test_{feature_key}_crud.py" output_file.write_text(code) output_file.chmod(0o755) ``` ### Technical Analysis The generator copies authentication credentials from the configuration into a persistent Python source file. The generated file therefore becomes an additional plaintext secret store. Mode `0755` makes the file readable by users other than its owner under normal Unix permission semantics. The output may also be indexed, backed up, attached to build artifacts, or committed to source control because it looks like an ordinary test script. When executed, the generated helper sends the embedded email and password to the configuration-selected login endpoint through `requests.post()`. Network transmission is part of the declared live-verification behavior, but persisting the credentials in generated source is unnecessary and exceeds minimum-privilege data handling. ### Attack Path 1. An operator places real test credentials in the JSON configuration. 2. The generator interpolates those credentials into a Python source file. 3. The file is written with mode `0755`. 4. Another local user, automated artifact collector, backup process, or source-control operation reads or copies the file. 5. The exposed credentials are used to authenticate ...[truncated 473 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not place passwords, access tokens, session cookies, or API keys in generated source. 2. Load credentials at execution time from environment variables, an interactive prompt using `getpass`, or an approved secret manager. 3. Fail closed if the required runtime secret is unavailable; do not provide a real-looking default password. 4. If any sensitive output must be written, create it atomically with mode `0600`. 5. Add generated-output paths and live configuration files to source-control ignore rules. 6. Document credential rotation and cleanup requirements. 7. Redact credentials from logs, exceptions, generated reports, and command output. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_tests.py:441
Finding
Untrusted configuration is interpolated into executable Python source<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_tests.py:441-475` **Vulnerability Type**: Generated-code injection **Risk Level**: High ### Vulnerable Code Multiple configuration-controlled values are inserted directly into an executable template: ```python code = TEST_TEMPLATE.format( feature_name=feature_name, timestamp=datetime.now().strftime('%Y-%m-%d %H:%M:%S'), service_name=service_name, api_base=api_base, auth_method=auth_config.get('method', 'header'), class_name=class_name, login_endpoint=test_account.get('login_endpoint', '/login'), login_request_encoding=login_request_encoding, email=test_account.get('email', 'test@example.com'), password=test_account.get('password', 'password'), token_extraction=token_extraction, user_id_extraction=user_id_extraction, auth_headers=generate_auth_headers(auth_config), http_create_method=create_method.lower(), create_endpoint=create_endpoint, create_request_encoding=create_request_encoding, create_user_binding=build_user_binding(create_include_user_id and not read_only, create_user_id_field), create_data=json.dumps(test_data if not read_only else {}), id_extraction=id_extraction, read_method=read_method_code, update_method=update_method_code, delete_endpoint=delete_endpoint, delete_request_encoding=delete_request_encoding, delete_payload_base='{}', delete_user_binding=build_user_binding(delete_include_user_id and not read_only, delete_user_id_field, 'payload'), delete_resource_id_binding=build_resource_id_binding(delete_include_resource_id and not read_only, delete_resource_id_field, 'payload'), http_delete_method=delete_method.lower(), test_sequence=test_sequence ) # Write file output_file = output_dir / f"test_{feature_key}_crud.py" output_file.write_text(code) output_file.chmod(0o755) ``` Examples of unsafe template contexts include quoted source literals and Python attribute na ...[truncated 2111 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace source generation with a fixed, reviewed runner that reads configuration strictly as data. 2. If source generation remains necessary, encode every string with `repr()` or another context-appropriate safe literal serializer. 3. Validate HTTP methods against a fixed allowlist rather than inserting arbitrary values into `requests.<method>` syntax. 4. Validate API URLs using a URL parser and restrict schemes to HTTPS, with explicit development exceptions if required. 5. Validate endpoint paths, class names, feature keys, field names, JSON extraction paths, and header names against strict schemas. 6. Reject unexpected properties and control characters in configuration. 7. Avoid generating arbitrary authentication-header source fragments; construct headers at runtime as dictionaries. 8. Create generated files with restrictive permissions and clearly label them as untrusted until reviewed. 9. Add tests using quote-breaking, newline, brace, and method-injection payloads to verify that generated output cannot escape data contexts. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill positions itself as audit-first and says live verification is secondary and limited, yet the behavior described in the finding includes generating and encouraging execution of write-capable live API tests with authentication handling. That mismatch is dangerous because users may trust it as a safe static analyzer and accidentally run state-changing requests against real services, causing data modification or operational impact.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill positions itself as audit-first and says live verification is secondary and limited, yet the behavior described in the finding includes generating and encouraging execution of write-capable live API tests with authentication handling. That mismatch is dangerous because users may trust it as a safe static analyzer and accidentally run state-changing requests against real services, causing data modification or operational impact.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
any_req = re.search(r'\.anyRequest\(\)\.(permitAll|authenticated)\s*\(', text)
        if any_req and any_req.group(1) == 'authenticated':
            rules.append((re.compile(r'^/.*'), RequestHints(auth=['authenticated-route'])))
    return rules


def match_security_hints(path: str, rules: List[Tuple[re.Pattern, RequestHints]]) -> RequestHints:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill instructs use of shell commands, file reads/writes, and potentially live verification, but it declares no explicit tool scope or permission boundaries. That omission can cause an agent runtime to over-grant capabilities, increasing the chance of unintended filesystem, environment, or network access during analysis or follow-up checks.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The finding summaries, unknown-status messages, and recommendations are written in Korean string literals, which imposes a specific language on downstream users or operators. The file does not offer a language/locale choice or explain that the tool is intentionally Korea-specific, so this appears to violate the language/locale policy.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The generated markdown includes multiple user-facing strings in Korean such as '위험도' and '즉시 확인할 항목'. This imposes a specific language on users without opt-in, which matches the natural-language locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The string '외 ...건' is another user-visible Korean phrase in the generated report. Combined with other Korean literals, this indicates the skill consistently forces a locale rather than offering user choice.

External Transmission

Medium
Category
Data Exfiltration
Content
}}

        if "{login_request_encoding}" == "json":
            r = requests.post(
                f"{{API_BASE}}{login_endpoint}",
                json=login_payload,
                timeout=10
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
This code deliberately generates runnable scripts that perform authenticated CREATE/UPDATE/DELETE requests against a configured API and then prints commands encouraging users to execute them. In an audit-first static contract analysis skill, that materially expands the trust boundary and creates risk of unintended state changes, notification triggers, quota consumption, or data corruption, especially because the production guard is heuristic and bypassable.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The main flow loads arbitrary configuration and generates executable test files that may send authenticated write requests whenever --allow-writes is supplied, which is a weak control for a skill whose stated purpose is static compatibility analysis. The surrounding warnings help, but they do not prevent misuse, and the generated output directly instructs operators to run the files, making accidental live impact plausible.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The code scans for `.env*` files and reads their contents to derive a default base path, which is a sensitive configuration source. There is no confirmation prompt, logging, comment, or docstring at this operation to disclose that environment-derived configuration files will be accessed.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
Using '없음' as a default output value is a user-facing language choice embedded directly in code. This is a smaller instance of the same locale policy issue because the skill does not provide opt-in or explain a Korean-only requirement.

Static analysis

No suspicious patterns detected.