Back to skill

Security audit

Homeassistant N8n Agent

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended to bridge OpenClaw to a local n8n/Home Assistant setup, but it needs review because it can trigger real smart-home actions and documents an unsafe raw curl pattern for user input.

Review this before installing. Use it only with a trusted local n8n workflow, require confirmation for any device-changing action, limit the workflow's Home Assistant and calendar permissions, and avoid constructing curl commands by substituting raw user text into a shell string.

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
SKILL.md:12
Finding

Command Injection Through Unsafe User Input Interpolation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 12
Vulnerability Type: Shell command injection through unsafe construction of a JSON request
Risk Level: High

Vulnerable Code

bash
Uses curl to trigger a n8n workflow for all things related to IoT.  All requests should be a POST formatted as follows: curl -X POST http://localhost:5678/webhook/05f3f217-08b9-42de-a84a-e13f135bde73 -H "Content-Type: application/json" -d '{"chatInput": "USERS QUESTION/REQUEST", "requestType": "DETERMINED REQUEST TYPE", "sessionId":"openclaw"}'

Technical Analysis

The skill instructs the agent to insert the user's question or request into a single-quoted JSON argument passed to curl. It does not require JSON serialization, shell escaping, input validation, or execution through a shell-free argument API.

If an implementation follows this template by textual substitution, a user-controlled single quote can terminate the shell argument. Subsequent shell metacharacters may then be interpreted as command syntax rather than JSON content. JSON escaping alone is insufficient because shell quoting and JSON encoding are separate security boundaries.

Although this file contains instructions rather than executable source code, the documented command is intended to be generated and executed by an agent. The vulnerability therefore becomes exploitable when the agent places prompt content directly into this template.

Attack Path

  1. An attacker submits an IoT-related request containing a single quote followed by shell syntax.
  2. The agent classifies the request and substitutes the original text into the chatInput field.
  3. The single quote closes the surrounding shell-quoted JSON argument.
  4. The shell interprets the remaining attacker-controlled content as command syntax.
  5. The injected command executes under the account and environment used to run the agent or curl.

Impact Assessment

Successful exploitat ...[truncated 628 chars]

Remediation
View remediation

Remediation Suggestions

  • Never construct the command by substituting user input into a shell command string.
  • Invoke curl through a process API that accepts an argument array and does not invoke a shell.
  • Generate the request body with a JSON serializer rather than manual string concatenation.
  • If command-line tooling is required, construct the body safely with jq, for example by passing input through --arg, and then provide the resulting JSON as one separately quoted argument.
  • Validate requestType against an explicit allowlist containing only state, action, historical, and calendar.
  • Treat chatInput exclusively as data and prevent it from affecting command names, options, headers, URLs, or shell syntax.
  • Add tests using quotes, backslashes, command separators, substitutions, and newline characters to verify that hostile input remains literal JSON data.
  • Correct the malformed state and calendar examples at lines 38 and 43 so implementations are not encouraged to generate invalid JSON.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (2)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs forwarding user prompts to an n8n webhook that can query device state, calendar data, and perform device actions, but it does not warn users that their requests are transmitted to another service and may trigger real-world changes. This is dangerous because users may unknowingly disclose sensitive home or calendar information or cause unintended automation actions without informed consent.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The skill explicitly sends raw user requests via curl POST to a local n8n webhook, including home-automation and calendar-related queries and commands. Even though the endpoint is localhost, this still constitutes external transmission to another service boundary and can expose sensitive household data or invoke physical actions if the receiving workflow is insecure, over-privileged, or insufficiently validated.

Content

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

md
This skill bridges OpenClaw with your n8n instance for Home Assistant automation.

# How it works
Uses curl to trigger a n8n workflow for all things related to IoT.  All requests should be a POST formatted as follows: curl -X POST http://localhost:5678/webhook/05f3f217-08b9-42de-a84a-e13f135bde73 -H "Content-Type: application/json" -d '{"chatInput": "USERS QUESTION/REQUEST", "requestType": "DETERMINED REQUEST TYPE", "sessionId":"openclaw"}'

# Steps
Determine the nature of a user's prompt.

Static analysis

No suspicious patterns detected.