Back to skill

Security audit

Expanso text-summarize

Security checks for vulnerabilities and agentic risk

Overview

This summarization skill is mostly coherent, but its MCP server exposes an unauthenticated OpenAI-backed endpoint on all network interfaces and its privacy wording understates what leaves the machine.

Review before installing. Use the local Ollama backend for sensitive text, or ensure users understand that OpenAI mode sends submitted text and authentication material to OpenAI. If using MCP mode, bind the service to 127.0.0.1, add authentication before exposing it beyond the local machine, and monitor API usage or spending limits.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
pipeline-mcp.yaml:27
Finding
Unauthenticated Network-Exposed OpenAI Inference Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `pipeline-mcp.yaml:27-34` and `pipeline-mcp.yaml:70-73` **Vulnerability Type**: Missing authentication and unrestricted network binding **Risk Level**: Medium ### Vulnerable Code ```yaml http: enabled: true address: "0.0.0.0:${PORT:-8080}" input: http_server: path: /summarize allowed_verbs: [POST] timeout: 60s ``` ```yaml - openai_chat_completion: api_key: "${OPENAI_API_KEY}" model: gpt-4o-mini ``` ### Technical Analysis The MCP pipeline binds its HTTP server to `0.0.0.0`, making it listen on every available network interface. The `/summarize` endpoint does not enforce authentication or authorization, and the configuration contains no rate limiting. Every accepted request invokes OpenAI using the API key supplied by the service operator. Consequently, any party able to reach the listening port can consume the operator's OpenAI quota without possessing that credential. The pipeline limits individual input text to 1 MB and applies a 60-second request timeout, but these controls do not prevent repeated or concurrent requests. Actual external exposure depends on host firewalls, container port mappings, cloud security groups, and surrounding network controls. ### Attack Path 1. An operator configures `OPENAI_API_KEY` and starts `pipeline-mcp.yaml`. 2. The service listens on port 8080, or the configured `PORT`, across all network interfaces. 3. A remote party discovers or otherwise reaches the exposed port. 4. The party submits unauthenticated `POST` requests to `/summarize` containing attacker-selected text. 5. The pipeline forwards each accepted request to OpenAI using the operator's API key. 6. The attacker repeats requests or sends requests concurrently, consuming API quota and service resources. ### Impact Assessment An attacker can invoke the summarization service and receive generated responses without authorization. This can result in: - Unauthorized consumption of th ...[truncated 563 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bind the service to the loopback interface by default: ```yaml http: enabled: true address: "127.0.0.1:${PORT:-8080}" ``` 2. If remote access is required, place the endpoint behind an authenticated reverse proxy or API gateway. Require a strong API token, mutual TLS, or another appropriate identity mechanism. 3. Enforce authorization so only explicitly approved clients can invoke the endpoint. 4. Add per-client and global rate limits, concurrency limits, request quotas, and OpenAI spending alerts. 5. Use TLS for all non-loopback traffic to prevent interception or modification in transit. 6. Restrict network exposure with host firewalls, container networking rules, cloud security groups, or private-network access controls. 7. Apply tighter input and generated-token limits based on expected use rather than relying only on the existing 1 MB body-size check. 8. Return generic error messages and monitor failed authentication, unusual request volume, latency, and quota consumption. ]]>
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

External Transmission

Medium
Category
Data Exfiltration
Content
# Start the skill server
PORT=8080 expanso-edge run pipeline-mcp.yaml &

# Call from curl (or OpenClaw MCP)
curl -X POST http://localhost:8080/summarize \
  -H "Content-Type: application/json" \
  -d '{"text": "Your long article or document text here..."}'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
For MCP mode, make sure you're sending JSON with a `text` field:

```bash
curl -X POST http://localhost:8080/summarize \
  -H "Content-Type: application/json" \
  -d '{"text": "Your text here"}'
```
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
95% confidence
Finding
The pipeline sends raw stdin content directly to an external AI service, which can expose sensitive user data if operators assume processing is local or do not realize third-party transmission occurs. The surrounding comments emphasize local API key handling, which may reduce attention to the more important privacy risk: the input text itself leaves the machine.

External Transmission

Medium
Category
Data Exfiltration
Content
#   # Start the server
#   PORT=8080 expanso-edge run pipeline-mcp.yaml
#
#   # Call from curl
#   curl -X POST http://localhost:8080/summarize \
#     -H "Content-Type: application/json" \
#     -d '{"text": "Your long text here..."}'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The pipeline enables an HTTP server and binds it to 0.0.0.0, exposing the summarization endpoint on all network interfaces without any authentication or access control. In MCP/local-agent contexts this increases the attack surface because any reachable host could submit arbitrary text for processing, consume resources, and potentially cause sensitive local data to be proxied to the external model if another local component feeds it in.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The HTTP listener is broadly exposed and the file does not define any invocation-scope constraints beyond accepting POST requests to /summarize. That means any network-reachable caller can invoke the skill, which is risky for an agent-side service intended to run on a user's machine and can lead to abuse, denial of service, or unauthorized use of local credentials-backed functionality.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill sends user-provided text directly to the OpenAI API, which is an external transmission of potentially sensitive content, yet the file lacks an explicit user-facing warning or consent mechanism at the point of use. In an MCP setting running on a local machine, users may incorrectly assume data stays entirely local because the service itself is local, making inadvertent disclosure more likely.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The manifest claims API keys are 'never transmitted,' but the skill explicitly defines a remote OpenAI backend that necessarily sends the API key to a third-party service for authentication. This is a misleading security/privacy claim that can cause users to trust the skill with sensitive data under false assumptions.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The manifest highlights local credential storage but omits that the optional remote backend sends user-provided text to an external provider. This omission can mislead users into submitting sensitive or regulated content without understanding that remote processing occurs.

Intent-Code Divergence

Low
Confidence
77% confidence
Finding
Lines L11-L12 make a strong behavioral claim that the OPENAI_API_KEY is 'never transmitted to Expanso Cloud or logged anywhere.' The code does resolve the key locally at L49, but nothing in this file proves or enforces the 'never logged anywhere' guarantee; that claim depends on runtime behavior outside the shown code. This is best treated as documentation overstating what the file itself guarantees.

Vague Triggers

Low
Confidence
84% confidence
Finding
This manifest says only "Summarize text into 3-5 bullet points using AI," which describes capability but does not define when the skill should activate or what trigger phrases should or should not invoke it. In a manifest file, that lack of trigger specificity can lead to unintended invocation overlap with generic summarization requests.

Static analysis

No suspicious patterns detected.