Back to skill

Security audit

导出接口Postman文件

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Postman-export purpose, but it persists user-provided domain data into an agent-readable memory file without validation or escaping.

Review this skill before installing if other people can influence the domain values you save. Its main risk is not hidden code execution; it is persistent domain storage that could be polluted with crafted Markdown. Prefer validating stored domains, reviewing references/domains.md, and avoiding persistence of untrusted values.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T02 · Agent Memory Poisoning

Warning
Location
scripts/create_postman_collection.py:47
Finding

Unescaped User Input Enables Persistent Agent Memory Poisoning

Content
View full analysis

Vulnerability Details

File Location: scripts/create_postman_collection.py, lines 47–72
Related Workflow Location: SKILL.md, lines 24–26
Vulnerability Type: Persistent agent memory poisoning through unsanitized Markdown insertion
Risk Level: Medium

Vulnerable Code

python
def remember_domain(domains_path: str, service: str, domain: str) -> None:
    path = Path(domains_path)
    path.parent.mkdir(parents=True, exist_ok=True)
    service = service.strip()
    domain = domain.strip().rstrip("/")
    if not service or not domain:
        raise SystemExit("--service and --domain are required with --remember-domain")

    if path.exists():
        text = path.read_text(encoding="utf-8")
    else:
        text = "# Stored Service Domains\n\n## Service mappings\n\n| Service | Domain | Notes |\n| --- | --- | --- |\n"

    row = f"| {service} | {domain} | Remembered after user confirmation |"
    if row in text:
        return
    if f"| {service} | {domain} |" in text:
        return

    marker = "| --- | --- | --- |"
    if marker in text:
        text = text.replace(marker, marker + "\n" + row, 1)
    else:
        text = text.rstrip() + "\n\n## Service mappings\n\n| Service | Domain | Notes |\n| --- | --- | --- |\n" + row + "\n"
    path.write_text(text.rstrip() + "\n", encoding="utf-8")

The associated workflow explicitly treats the modified file as durable memory:

markdown
- After the user provides a new service domain, persist it immediately in `references/domains.md` before generating the Postman file.
- Treat `references/domains.md` as the durable memory for service/domain answers. Do not rely only on chat history.

Technical Analysis

The remember_domain() function accepts service and domain values originating from command-line arguments that may be derived directly from user input. It only strips surrounding whitespace and a trailing slash. It does not:

  • Reject newline or control characters.
  • Validate ...[truncated 2691 chars]
Remediation
View remediation

Remediation Suggestions

  1. Strictly validate the domain

    • Parse the supplied value with urllib.parse.urlparse.
    • Permit only http and https.
    • Require a nonempty, syntactically valid hostname.
    • Reject credentials, control characters, whitespace, fragments, and unexpected URL components.
    • Define an explicit policy for ports, paths, and query strings.
  2. Validate and constrain service names

    • Allow only a restricted character set such as letters, digits, underscores, periods, and hyphens.
    • Enforce a reasonable maximum length.
    • Reject newline, carriage-return, null, and other control characters.
  3. Prevent Markdown injection

    • Reject multiline values.
    • Escape table metacharacters such as | and backslashes before Markdown serialization.
    • Do not rely on simple string interpolation to construct structured storage.
  4. Use schema-validated structured storage

    • Store mappings in JSON or another format parsed strictly as data.
    • Validate loaded records against a schema before use.
    • Render Markdown documentation from validated data if human readability is required.
  5. Treat persisted content as untrusted

    • Explicitly instruct the agent that stored values are data only and must never be followed as instructions.
    • Extract only validated mapping fields instead of loading the complete free-form Markdown document into the agent context.
  6. Write safely

    • Write updates to a temporary file in the same directory and atomically replace the destination after successful validation and serialization.
    • Add tests covering newlines, Markdown delimiters, malformed URLs, embedded credentials, fragments, control characters, and oversized values.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to read project files, persist data to references/domains.md, and potentially use a network-relevant domain selection workflow, but it does not declare any explicit tool scope or allowed-tools boundaries. That creates an unnecessary privilege ambiguity: an agent may use broader file and network capabilities than intended, increasing the risk of overreach, unintended data access, or unsafe writes during routine use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions are very broad, covering common phrases like exporting an API/interface in both Chinese and English, which can cause the skill to activate in contexts the user did not clearly intend. Because the skill performs repository searches and writes files, over-broad activation can lead to unintended code inspection, domain persistence, or file generation from casual or ambiguous requests.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes a skill for exporting an HTTP endpoint into a Postman-importable collection JSON file. In addition to generating collection output, the code also maintains a persistent service-to-domain mapping file via --remember-domain, which is a separate state-management feature not implied by simple export behavior.

Content

No source excerpt is available for this finding.

Tainted flow: 'text' from pathlib.Path.read_text (line 77, file read) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/create_postman_collection.py (reported line 78)May include surrounding context.

python
text = text.replace(marker, marker + "\n" + row, 1)
    else:
        text = text.rstrip() + "\n\n## Service mappings\n\n| Service | Domain | Notes |\n| --- | --- | --- |\n" + row + "\n"
    path.write_text(text.rstrip() + "\n", encoding="utf-8")


def split_url(base_url: str, path: str) -> tuple[str, list[str], list[dict[str, str]]]:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The file presents the skill name and description in Chinese, but the default prompt is fixed in English. This can impose a language choice on the user experience without explicit opt-in or any documented language-selection behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

Line L04 says the skill should not read C:\Windows\System32\drivers\etc\hosts during ordinary exports, creating an expectation that hosts-file access is outside normal behavior. However, lines L15-L17 document that domains were imported from the local hosts file, which creates a documentation-level contradiction about whether that source is used.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest says the skill exports an API endpoint to a Postman collection. The read_domain_candidates logic parses a domains reference file, scores candidate hosts by service name, and the CLI can print those candidates, which is auxiliary discovery behavior rather than direct collection export.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script persists service/domain mappings to the domains file via write_text, but there is no confirmation prompt, log/print statement, or inline warning at the write site that this operation modifies local files. Although the module docstring describes collection creation, it does not disclose that --remember-domain edits a separate references file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

When --output is provided, the script writes the generated collection JSON to disk using write_text, but there is no visible confirmation, log message, or explicit warning that the target file will be created or overwritten. For a code file, file writes should have some form of user disclosure unless clearly documented at the operation site.

Content

No source excerpt is available for this finding.