Back to skill

Security audit

MCP Security Audit & Config Checkup

Security checks for vulnerabilities and agentic risk

Overview

The skill is a local MCP config scanner by default, but its optional online mode can upload full configs and credentials to an endpoint that can be overridden.

Install only if you intend to use local mode or you are comfortable with the online workflow. Avoid --online unless you knowingly want to send the full MCP configuration to a hosted service; do not use --endpoint or CCS_API_ENDPOINT with untrusted hosts, and clear CCS_API_TOKEN, CCS_PAYMENT_PROOF, and CCS_PAY_TOKEN unless needed for a trusted service.

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

Error
Location
scripts/ccs_online_client.py:58
Finding
Full MCP Configuration and Authentication Secrets Can Be Sent to an Environment-Controlled Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ccs_online_client.py:58-105` **Vulnerability Type**: Untrusted endpoint selection and sensitive-data disclosure **Risk Level**: High ### Vulnerable Code ```python def resolve_endpoint(cli_value: str | None = None) -> str: ep = cli_value or os.environ.get("CCS_API_ENDPOINT") or DEFAULT_ENDPOINT return ep.rstrip("/") ``` ```python ep = resolve_endpoint(endpoint) data = json.dumps(body, ensure_ascii=False).encode("utf-8") if len(data) > MAX_BODY_BYTES: raise CCSAPIError(413, {"error": f"请求体超过 {MAX_BODY_BYTES} 字节上限"}) headers = {"Content-Type": "application/json; charset=utf-8", "User-Agent": "CCS-CLI/1.0 (channel=clawhub)"} api_key = os.environ.get("CCS_API_TOKEN") if api_key: headers["X-API-Key"] = api_key # A2M: payment proof from the Alipay checkout flow (official contract # header name is Payment-Proof). CCS_PAY_TOKEN kept as a legacy alias. proof = os.environ.get("CCS_PAYMENT_PROOF") or os.environ.get("CCS_PAY_TOKEN") if proof: headers["Payment-Proof"] = proof req = urllib.request.Request(ep + path, data=data, headers=headers, method="POST") ``` The online call is reached through `scripts/mcp_checkup.py:112-122` and `scripts/mcp_checkup.py:175-176` when the user supplies the explicit `--online` option. ### Technical Analysis Online mode serializes the complete input body and submits it without redaction. MCP configurations are likely to contain API keys, cloud credentials, access tokens, internal endpoint addresses, filesystem paths, and infrastructure details—the same kinds of sensitive values this Skill is designed to identify. The destination is selected in the following order: 1. The command-line `--endpoint` value. 2. The inherited `CCS_API_ENDPOINT` environment variable. 3. The hardcoded Correctover service endpoint. The resolved endpoint is not restricted to a ...[truncated 3100 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Restrict online submissions to approved destinations** - Remove `CCS_API_ENDPOINT` as an implicit environment-based override for production use. - Maintain an explicit allowlist of permitted HTTPS hostnames. - Reject URLs containing user information, unexpected ports, fragments, or non-HTTPS schemes. - Resolve and validate the final destination before constructing the request. 2. **Bind credentials to the trusted service** - Add `X-API-Key` and `Payment-Proof` only when the resolved scheme and hostname exactly match an approved service. - Never forward service credentials to arbitrary command-line or environment-supplied endpoints. - Consider separate credentials for custom/private deployments. 3. **Require informed confirmation** - Display the resolved destination hostname before transmitting data. - Require explicit confirmation when the endpoint differs from the default. - Clearly warn that online mode sends the configuration off-device and may expose embedded secrets. 4. **Minimize transmitted data** - Run local secret detection first. - Redact or tokenize detected credential values before submission. - Prefer sending only the fields required for analysis rather than the complete configuration. - Refuse online submission when high-confidence secrets are found unless the user explicitly overrides the refusal. 5. **Enforce transport security** - Reject plaintext HTTP endpoints. - Use TLS certificate verification, which is enabled by default in standard `urllib`, and do not provide insecure bypasses. - Consider certificate or public-key pinning if the operational environment supports secure pin rotation. 6. **Harden environment handling** - Treat inherited endpoint variables as untrusted input. - Log the selected endpoint hostname without logging request bodies or credentials. - In CI and agent environments, use a sanitized environment and narrowly scoped cre ...[truncated 333 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Tainted flow: 'req' from os.environ.get (line 104, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
req = urllib.request.Request(ep + path, data=data, headers=headers,
                                 method="POST")
    try:
        with urllib.request.urlopen(req, timeout=timeout) as r:
            return json.loads(r.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        try:
Confidence
97% confidence
Finding
The request sent via urllib includes data derived from environment-controlled inputs: the endpoint can be overridden by CCS_API_ENDPOINT, and sensitive headers are populated from CCS_API_TOKEN and CCS_PAYMENT_PROOF/CCS_PAY_TOKEN. This creates a real exfiltration risk because a user or orchestrator can be induced to send credentials and request bodies to an arbitrary remote server, which is especially dangerous given the skill’s stated purpose should require no network access at all.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The skill is marketed repeatedly as 'local', 'zero network by default', and 'no network connection is ever made', but it also exposes an online mode that submits the analyzed config to a hosted service and uses auth/payment-related headers. Even if opt-in, this creates a trust-boundary shift: users may provide sensitive MCP configs expecting purely local handling and could inadvertently exfiltrate secrets or internal endpoints when online mode is enabled.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
This file performs live outbound HTTP requests to a remote API, directly contradicting the manifest claim that the skill runs 100% locally with zero network calls. Such capability materially changes the trust model: data supplied for a security audit may be transmitted off-host, enabling exfiltration, remote dependency abuse, or deceptive behavior under a false-local banner.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The code implements a remote CCS API client with payment-proof and API-token handling, which is unrelated to a local MCP configuration security audit. This unjustified functionality increases attack surface and suggests the skill may route user data and secrets to an external service under misleading pretenses.

Intent-Code Divergence

Medium
Confidence
87% confidence
Finding
The docstring downplays credential handling by stating the script does not touch merchant key material, but the implementation does ingest and transmit sensitive authentication artifacts such as API tokens and payment proof headers. Misleading security claims can cause operators to use the tool in higher-trust contexts than warranted, increasing the chance of accidental secret disclosure.

Description-Behavior Mismatch

High
Confidence
94% confidence
Finding
The script and skill metadata strongly emphasize 'zero network calls' and local-only analysis, yet the implementation includes an online mode that can submit supplied configuration data to a hosted service. This creates a trust-boundary mismatch: users may provide sensitive MCP configs under the assumption they will never leave the machine, and accidental or misunderstood use of --online could expose secrets or internal endpoints.

Context-Inappropriate Capability

Medium
Confidence
82% confidence
Finding
The hosted-service submission path sends the analyzed body to a remote endpoint, which may include sensitive MCP configuration details such as tokens, internal URLs, mounts, or command definitions. In a security-audit tool context, transmitting the very material being audited increases confidentiality risk and can violate user expectations even if it is user-invoked.

Vague Triggers

High
Confidence
99% confidence
Finding
The filesystem server is launched with '/' as its allowed root, which grants effectively unrestricted access to the host filesystem through the MCP server. In this same config, hardcoded cloud and GitHub credentials are present, so broad file access materially increases the chance of credential discovery, sensitive file exfiltration, and host-level data exposure if the agent or connected tools are abused.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The configuration uses plaintext HTTP for an MCP endpoint, which allows traffic to be intercepted or modified by any local network adversary if the service is ever bound beyond a strictly trusted boundary. Although 'localhost' reduces exposure compared with a remote host, this skill’s purpose is security review of MCP configs, and insecure transport is still a meaningful weakness because it normalizes unsafe defaults and can become dangerous if the deployment context changes.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
raise CCSAPIError(413, {"error": f"请求体超过 {MAX_BODY_BYTES} 字节上限"})
    headers = {"Content-Type": "application/json; charset=utf-8",
               "User-Agent": "CCS-CLI/1.0 (channel=clawhub)"}
    api_key = os.environ.get("CCS_API_TOKEN")
    if api_key:
        headers["X-API-Key"] = api_key
    # A2M: payment proof from the Alipay checkout flow (official contract
Confidence
95% confidence
Finding
Reading CCS_API_TOKEN from the environment and attaching it to outbound requests is a real secret-handling path. In this skill context, where network access is unexpected and endpoint selection can be environment-controlled, this becomes dangerous because secrets can be silently forwarded to external infrastructure or attacker-chosen destinations.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
headers["X-API-Key"] = api_key
    # A2M: payment proof from the Alipay checkout flow (official contract
    # header name is Payment-Proof). CCS_PAY_TOKEN kept as a legacy alias.
    proof = os.environ.get("CCS_PAYMENT_PROOF") or os.environ.get("CCS_PAY_TOKEN")
    if proof:
        headers["Payment-Proof"] = proof
    req = urllib.request.Request(ep + path, data=data, headers=headers,
Confidence
97% confidence
Finding
The script reads CCS_PAYMENT_PROOF or CCS_PAY_TOKEN from environment variables and sends the value as a Payment-Proof header to the remote endpoint. Payment proofs are sensitive bearer-style artifacts; forwarding them to a malicious or misconfigured endpoint could enable payment fraud, replay, or unauthorized billing-related actions.

Static analysis

Detected: suspicious.install_untrusted_source

Install source points to URL shortener or raw IP.

Warn
Code
suspicious.install_untrusted_source
Location
examples/mcp_dangerous.json:19