Back to skill

Security audit

图文笔记发布

Security checks for vulnerabilities and agentic risk

Overview

This skill appears purpose-built for publishing notes, but it deserves Review because it can send drafts and image paths to any configured backend and perform live posts without strong safeguards.

Install only if you fully trust the MCP backend you configure and understand that running the script can publish real content from your account. Prefer localhost or audited HTTPS backends, avoid sensitive drafts or private image paths, and test with non-production accounts before batch publishing.

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

Warning
Location
scripts/publish.py:73
Finding

Unrestricted Cleartext MCP Communication with Forced Proxy Bypass

Content
View full analysis

Vulnerability Details

File Location: scripts/publish.py, lines 73–82 and 95–102
Vulnerability Type: Unvalidated backend URL, permitted cleartext transport, and forced proxy bypass
Risk Level: Medium

Vulnerable Code

python
def curl(payload, session=None, timeout=300):
    """Send an MCP JSON-RPC request and return the response body."""
    cmd = [
        "curl", "--noproxy", "*", "-s", "--max-time", str(timeout),
        "-X", "POST", MCP_URL,
        "-H", "Content-Type: application/json",
    ]
    if session:
        cmd += ["-H", "Mcp-Session-Id: {}".format(session)]
    cmd += ["-d", json.dumps(payload, ensure_ascii=False)]
python
cmd = [
    "curl", "--noproxy", "*", "-s", "-i", "--max-time", "30",
    "-X", "POST", MCP_URL, "-H", "Content-Type: application/json",
    "-d", json.dumps(init_payload),
]

Technical Analysis

The script obtains MCP_URL from the MCP_PUBLISHER_URL environment variable or config.json but does not validate its scheme, host, port, or destination. Plain HTTP is explicitly supported by the documented example.

Both request paths also use curl --noproxy "*". This forces every MCP request to bypass configured HTTP and HTTPS proxies, even when the endpoint is remote. As a result, organizational egress controls, monitoring gateways, or security proxies that the execution environment expects to apply are bypassed.

The script transmits MCP initialization data, publication titles and bodies, tags, local image path strings, and MCP session identifiers through this channel. It also accepts session identifiers and profile responses from the configured endpoint. When a non-loopback endpoint uses HTTP, an on-path attacker can observe or modify these exchanges.

Using subprocess.run() with an argument array prevents shell metacharacters in MCP_URL from becoming ordinary shell command injection. The confirmed issue is therefore insecure destination and transport handling, not shell injection. ...[truncated 1536 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse the configured URL with a strict URL parser before invoking curl.
  2. Permit only https for non-loopback destinations. If local development requires HTTP, restrict it to explicit loopback hosts such as 127.0.0.1, [::1], or a carefully validated localhost.
  3. Reject URLs with unsupported schemes, missing hosts, embedded credentials, fragments, or malformed ports.
  4. Remove --noproxy "*". Respect the host environment's proxy policy by default.
  5. If proxy bypass is necessary for local services, apply it only after validating that the destination resolves exclusively to an approved loopback address.
  6. Preserve TLS certificate and hostname verification; do not introduce curl --insecure.
  7. Consider an explicit endpoint allowlist for automated or managed deployments.
  8. Check curl return codes and standard error, and fail closed on TLS, transport, or HTTP errors rather than treating an empty or malformed response as ordinary output.
  9. Avoid printing the full configured URL if it can contain credentials or sensitive query parameters.
  10. Document the security boundary clearly: the configured MCP backend receives publication data and should be trusted and authenticated.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (8)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README tells users to send Markdown content, images, and rely on login-state handling through a user-specified MCP backend, but it does not clearly warn that all post content and potentially sensitive session-related data are being transmitted to a separate service. This is dangerous because users may trust the skill as a local-only helper and unknowingly expose unpublished content, private images, or account-related data to an untrusted or misconfigured backend.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The publishing section describes one-command posting and login reuse without warning that publication is a live remote action that may be immediate and difficult or impossible to undo on the target platform. This can cause accidental public disclosure, spam, compliance issues, or unintended account activity if the user misunderstands the effect of running the command.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill describes use of environment variables, local file inputs, and shell commands (python3 scripts/publish.py ...) but does not declare any explicit tool scope such as permissions or allowed-tools. That creates a capability mismatch where an agent may invoke file, env, or shell access without clear confinement, increasing the risk of unintended local data exposure or unsafe command execution if the skill is auto-enabled.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are broad enough that the skill may activate for generic publishing or login-related requests, causing an agent to route users into a workflow that reads local markdown, images, and backend configuration unnecessarily. In this context, the skill also relies on a user-supplied MCP backend URL, so accidental activation could lead to unintended interaction with sensitive local content or an untrusted publishing service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file’s user-facing docstring, CLI help, and operational messages are entirely in Chinese, which imposes a specific language on users without any opt-in or alternative locale support. The policy explicitly flags language or locale constraints when the skill forces a specific language without user choice.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/publish.py (reported line 74)May include surrounding context.

python
if session:
        cmd += ["-H", "Mcp-Session-Id: {}".format(session)]
    cmd += ["-d", json.dumps(payload, ensure_ascii=False)]
    p = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout + 30)
    return p.stdout

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/publish.py (reported line 90)May include surrounding context.

python
"-X", "POST", MCP_URL, "-H", "Content-Type: application/json",
        "-d", json.dumps(init_payload),
    ]
    p = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
    sid = ""
    for line in p.stdout.splitlines():
        if line.lower().startswith("mcp-session-id:"):

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest and module docstring emphasize a generic publishing framework that handles login and publish orchestration, not broader account data access. However, after publish the script calls get_my_profile and inspects feeds to recover a note ID, which extends behavior beyond pure publish orchestration into reading account/profile content.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.