Back to skill

Security audit

Manus AI Skill for OpenClaw

Security checks for vulnerabilities and agentic risk

Overview

The skill is a mostly coherent Manus API integration, but it exposes broad remote-agent, file-upload, connector, and webhook capabilities without enough scoping or safety controls.

Install only if you intend to use Manus as a remote autonomous service. Do not upload secrets or sensitive documents unless you accept sending them to Manus, use least-privilege/test connector accounts where possible, review prompts before asking it to act in Gmail/Slack/Calendar/Notion, and avoid exposing the webhook server publicly without authentication and request limits.

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/webhook_server.py:38
Finding

Publicly Exposed Webhook Receiver Lacks Authentication and Request-Size Limits

Content
View full analysis

Vulnerability Details

File Location: scripts/webhook_server.py, lines 38–59 and line 174
Vulnerability Type: Unauthenticated webhook processing and unbounded request-body handling
Risk Level: Medium

Vulnerable Code

python
def do_POST(self):
    """Handle webhook POST requests."""
    if self.path == "/webhook/manus":
        content_length = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(content_length)
        
        try:
            data = json.loads(body.decode("utf-8"))
            self.handle_manus_webhook(data)
            
            self.send_response(200)
            self.send_header("Content-Type", "application/json")
            self.end_headers()
            self.wfile.write(b'{"status": "ok"}')
            
        except Exception as e:
            print(f"❌ Error processing webhook: {e}")
            self.send_response(400)
            self.end_headers()
    else:
        self.send_response(404)
        self.end_headers()
python
server = HTTPServer(("0.0.0.0", args.port), WebhookHandler)

Technical Analysis

The HTTP server binds to 0.0.0.0, making it reachable through every available network interface unless external firewall rules prevent access. The webhook endpoint accepts JSON events without verifying a cryptographic webhook signature, shared secret, timestamp, source identity, or other proof that the request originated from Manus.

The handler also converts the attacker-controlled Content-Length header to an integer and passes it directly to self.rfile.read() without enforcing a maximum request size. This permits excessive memory consumption and allows clients to hold the single-threaded server while slowly transmitting a declared request body.

Attacker-controlled event fields—including task identifiers, titles, and error messages—are printed to the terminal without sanitizing control characters ...[truncated 1514 chars]

Remediation
View remediation

Remediation Suggestions

  1. Bind to 127.0.0.1 by default. Require an explicit command-line option to listen on public or non-loopback interfaces.
  2. Verify the webhook provider's cryptographic signature over the raw request body. Reject requests with missing, malformed, stale, or invalid signatures, and use constant-time comparison where applicable.
  3. Add replay protection by validating a signed timestamp and rejecting events outside a short permitted time window. Track event identifiers if the provider supports them.
  4. Enforce a small maximum request-body size before calling read(). Return HTTP 413 Payload Too Large when the declared size exceeds the limit.
  5. Configure connection and read timeouts. Consider a hardened, concurrent production HTTP server when public exposure is required.
  6. Require an appropriate JSON Content-Type and validate the event payload against a strict schema before processing it.
  7. Sanitize carriage returns, newlines, escape sequences, and other terminal-control characters before printing remote fields.
  8. Place any externally reachable deployment behind a TLS-enabled reverse proxy with firewall rules, rate limiting, and request-size limits.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (43)

Tainted flow: 'headers' from os.environ.get (line 28, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/create_project.py (reported line 38)May include surrounding context.

python
"description": description
    }
    
    response = requests.post(url, json=data, headers=headers)
    
    if response.status_code != 200:
        print(f"❌ Error: {response.text}")

Tainted flow: 'headers' from os.environ.get (line 28, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/check_status.py (reported line 33)May include surrounding context.

python
"API_KEY": api_key
    }
    
    response = requests.get(url, headers=headers)
    
    if response.status_code != 200:
        print(f"❌ Error: {response.text}")

Tainted flow: 'headers' from os.environ.get (line 28, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/get_result.py (reported line 33)May include surrounding context.

python
"API_KEY": api_key
    }
    
    response = requests.get(url, headers=headers)
    
    if response.status_code != 200:
        print(f"❌ Error: {response.text}")

Tainted flow: 'headers' from os.environ.get (line 64, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/run_task.py (reported line 53)May include surrounding context.

python
if title:
        data["title"] = title
    
    response = requests.post(url, json=data, headers=headers)
    
    if response.status_code != 200:
        print(f"❌ Error creating task: {response.text}")

Tainted flow: 'headers' from os.environ.get (line 64, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/run_task.py (reported line 69)May include surrounding context.

python
"API_KEY": api_key
    }
    
    response = requests.get(url, headers=headers)
    
    if response.status_code != 200:
        print(f"❌ Error getting task: {response.text}")

Tainted flow: 'headers' from os.environ.get (line 32, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/upload_file.py (reported line 38)May include surrounding context.

python
with open(file_path, "rb") as f:
        files = {"file": (os.path.basename(file_path), f)}
        response = requests.post(url, files=files, headers=headers)
    
    if response.status_code != 200:
        print(f"❌ Error uploading: {response.text}")

Tainted flow: 'headers' from os.environ.get (line 106, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/webhook_server.py (reported line 120)May include surrounding context.

python
]
    }
    
    response = requests.post(url, json=data, headers=headers)
    
    if response.status_code != 200:
        print(f"❌ Error registering webhook: {response.text}")

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description claims a general-purpose autonomous Manus AI agent with expansive capabilities, but the provided code only implements a narrow status-checking script for existing Manus tasks. It fetches an API key, calls the Manus tasks endpoint, and displays task metadata. This is a materially different primary purpose from the declared agent capabilities, so the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a broad autonomous AI agent with research, development, automation, and media-generation capabilities. The supplied code instead implements a narrow utility script whose sole purpose is to create a Manus project through the Manus REST API using an API key from environment variables or a local config file. This is a materially different primary purpose and includes concrete external API/project-management behavior not reflected in the description. Therefore, the description does not accurately represent the code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The description claims a broad autonomous Manus AI agent with multiple high-level capabilities, but the provided code only implements a narrow result-retrieval script. Its primary purpose is to look up a Manus task by ID, using an API key from an environment variable or local config file, then print extracted assistant text and metadata. It does not perform autonomous task execution, research, development, automation, or media generation itself. The code also accesses local configuration and the Manus API, which are operational details not reflected in the declared purpose. This is a material description-to-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a broad autonomous AI agent with research, development, automation, and media-generation capabilities. The supplied code does not implement those agent behaviors; it is a narrow helper script whose sole purpose is uploading a local file to Manus via HTTP. It accesses local filesystem paths, reads credentials from environment variables and a local config file, and sends file contents to an external API. Those are materially different concrete behaviors from the declared purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

La descripción declarada presenta un agente de IA autónomo de propósito amplio con capacidades de investigación, desarrollo, automatización y generación de medios. Sin embargo, este fragmento no implementa ninguna de esas capacidades principales. Su función real es mucho más específica e infraestructural: abrir un servidor HTTP en 0.0.0.0, aceptar POST en /webhook/manus, procesar eventos task.created/task.completed/task.failed y, opcionalmente, registrar el webhook usando una API key. Esto constituye un propósito materialmente distinto y añade capacidades de red/recepción de eventos no reflejadas en la descripción. Aunque esté relacionado con Manus, la descripción no representa con precisión este comportamiento concreto.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/run_task.py (reported line 18)May include surrounding context.

python
DEFAULT_TIMEOUT = 120  # seconds

def get_api_key():
    """Get API key from environment or config."""
    api_key = os.environ.get("MANUS_API_KEY")
    
    # Try to read from config file

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README encourages use of Gmail, Notion, Google Calendar, and Slack actions that can read or modify third-party account data, but it does not warn users that these operations may access private content or create external side effects. In an autonomous agent skill, this omission is risky because users may invoke actions without understanding privacy exposure or account-impact consequences.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file upload section tells users to upload local files for context but does not clearly disclose that file contents will be transmitted to the external Manus service. Because this skill is designed for autonomous research and analysis, users may inadvertently send sensitive local documents, credentials, or proprietary data off-system.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill declares access to environment variables and external network services but does not define an explicit permission or allowed-tools scope. For a skill that can read API keys and send prompts, files, and task data to a remote service, this weakens reviewability and can enable over-broad use beyond what a user may expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill advertises internet access and actions through authenticated connectors but does not clearly warn users that prompts, retrieved data, and account content may be transmitted to or acted on by an external service. In this context, the omission increases the chance of accidental disclosure of sensitive emails, documents, calendar data, or internal messages.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The skill explicitly sends task data to an external API endpoint. In this skill context, prompts may contain sensitive business data and can be combined with authenticated-service actions, so external transmission is security-relevant and should be treated as a real data-exposure surface.

Content

Scanner excerpt · SKILL.md (reported line 28)May include surrounding context.

md
| Endpoint | Descripción |
|----------|-------------|
| `https://api.manus.ai/v1/tasks` | Crear y gestionar tareas |
| `https://api.manus.ai/v1/projects` | Gestión de proyectos |
| `https://api.manus.ai/v1/files` | Subir archivos |
| `https://api.manus.ai/v1/webhooks` | Webhooks para notificaciones |

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

Project-management requests are transmitted to the external Manus projects endpoint using stored credentials. This creates a real external control and data-flow surface, especially if project names/descriptions include confidential information or trigger actions in a linked remote environment.

Content

Scanner excerpt · SKILL.md (reported line 29)May include surrounding context.

md
| Endpoint | Descripción |
|----------|-------------|
| `https://api.manus.ai/v1/tasks` | Crear y gestionar tareas |
| `https://api.manus.ai/v1/projects` | Gestión de proyectos |
| `https://api.manus.ai/v1/files` | Subir archivos |
| `https://api.manus.ai/v1/webhooks` | Webhooks para notificaciones |

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The files endpoint is a concrete exfiltration channel because local file contents are uploaded to an external service. Given the skill's stated workflow around context files and analysis, users may unintentionally transmit proprietary, personal, or secret material.

Content

Scanner excerpt · SKILL.md (reported line 30)May include surrounding context.

md
|----------|-------------|
| `https://api.manus.ai/v1/tasks` | Crear y gestionar tareas |
| `https://api.manus.ai/v1/projects` | Gestión de proyectos |
| `https://api.manus.ai/v1/files` | Subir archivos |
| `https://api.manus.ai/v1/webhooks` | Webhooks para notificaciones |

## Uso Básico

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

Webhook registration involves transmitting endpoint information and enabling asynchronous callbacks with an external service. In this skill context, that increases exposure by linking a local or user-controlled endpoint to remote events, which can reveal metadata and open a network-reachable integration surface.

Content

Scanner excerpt · SKILL.md (reported line 31)May include surrounding context.

md
| `https://api.manus.ai/v1/tasks` | Crear y gestionar tareas |
| `https://api.manus.ai/v1/projects` | Gestión de proyectos |
| `https://api.manus.ai/v1/files` | Subir archivos |
| `https://api.manus.ai/v1/webhooks` | Webhooks para notificaciones |

## Uso Básico

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The Gmail, Slack, Notion, and Calendar examples encourage actions against authenticated services without explicit notice that the skill may read from or modify those connected accounts. In a skill with broad automation claims, this can mislead users into exposing sensitive organizational data or triggering unintended side effects in production accounts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The upload_file documentation tells users to send local files to the Manus API without warning that file contents leave the local environment and are transmitted to a third party. This is dangerous because users may upload secrets, internal documents, or regulated data under the assumption they remain local.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The OpenAI-compatible example shows chat completion content being sent to Manus via a custom base_url. This is a real external transmission path and can be mistaken for local model use unless the docs make the remote destination and data-sharing implications explicit.

Content

Scanner excerpt · SKILL.md (reported line 185)May include surrounding context.

md
client = OpenAI(
    api_key="sk-...",  # Tu API key de Manus
    base_url="https://api.manus.ai/v1"
)

response = client.chat.completions.create(

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

The usage-check curl command sends account-authenticated requests to an external endpoint. The risk is lower than file upload or connector actions, but it still involves remote disclosure of account usage metadata and demonstrates use of sensitive credentials in command examples.

Content

Scanner excerpt · SKILL.md (reported line 252)May include surrounding context.

Las tareas consumen créditos. Ver uso con:

bash
curl "https://api.manus.ai/v1/usage" \
  -H "API_KEY: sk-..."

Static analysis

No suspicious patterns detected.