T09 · Insecure Skill Coding Practices
- Location
src/webhook-server.js:113- Finding
Caller-Controlled Callback URL Enables SSRF and Sensitive Data Exfiltration
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This n8n integration is coherent but needs Review because its webhook server can trigger agents and send results plus its token to caller-supplied callback URLs.
Install only in a controlled local or private environment after setting strong unique secrets, replacing the documented default token, restricting callback URLs to trusted n8n endpoints, avoiding token forwarding to callbacks, and reviewing n8n API permissions before enabling workflow deletion or credential access.
src/webhook-server.js:113Caller-Controlled Callback URL Enables SSRF and Sensitive Data Exfiltration
src/webhook-server.js:21Publicly Documented Hard-Coded Default Authentication Token
src/webhook-handler.js:11Secondary Webhook Handler Silently Disables Authentication
src/webhook-handler.js:42Unbounded Webhook Request Body Accumulation Enables Memory Exhaustion
src/webhook-server.js:21Configured Callback Timeout Is Not Enforced
Referenced artifact was not completely inspected
node src/webhook-server.js
The lockfile includes path-to-regexp 0.1.12, which the advisory flags for Regular Expression Denial of Service. In an Express-based integration, route matching occurs on inbound requests, so a vulnerable route parser can make externally reachable endpoints susceptible to CPU exhaustion from crafted paths, making this materially relevant in context.
The file content consistently forces a specific language for skill documentation and instructions, and there is no indication that users may choose another language or that the skill is intentionally region-specific. Under SQP-3, a language/locale policy violation exists when a specific language is imposed without user opt-in or documented justification.
This markdown specifies a flow where n8n triggers a webhook, the agent executes using request parameters, and results are sent back via callback. For markdown files, SQP-2 applies when the description omits warnings about behaviors that could affect privacy or system integrity; here, data is sent over webhooks/HTTP with no caution about what data may be transmitted or exposed.
The documentation explicitly advertises automatic callbacks of agent execution results to a caller-supplied callback URL, but it does not warn users that results may be transmitted to arbitrary external endpoints. In an agent context, execution results can contain sensitive prompts, tool output, internal data, or user content, so this creates a real risk of unintended exfiltration or SSRF-like outbound delivery if callback destinations are not constrained.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
curl -X POST http://localhost:3002/webhook/trigger \
-H "Content-Type: application/json" \
-H "X-N8N-Token: n8n-webhook-token" \
-d '{
The CRM example shows agent output being used to update external business records, but the skill does not warn that this integration can modify third-party or production data. That omission is risky because users may deploy the workflow without approval gates, validation, or human review, allowing incorrect or manipulated agent output to alter important records.
The workflow exposes a POST webhook on a fixed path and immediately forwards attacker-controlled fields to an internal service without any visible authentication, origin restriction, input validation, or trigger constraints. In this context, the broad webhook is more dangerous because it acts as an unauthenticated entry point that can invoke downstream agent behavior and pass through arbitrary callback URLs and parameters.
This JavaScript file contains natural-language content in comments and log messages exclusively in Chinese, such as the header description and startup/shutdown messages. Under the stated policy, forcing a specific language without user opt-in is a language/locale policy violation unless the locale restriction is explicitly justified.
The code exposes a destructive delete operation via deleteWorkflow() but provides no confirmation prompt, logging, or explicit warning beyond the brief method comment. For a code file, destructive or irreversible operations should have some visible disclosure unless the warning is documented elsewhere, which is not shown in this file.
listCredentials() retrieves credential-related data from the n8n API, which is a sensitive operation, but the file does not include any user-facing warning, logging, or explicit explanatory comment beyond the generic method label. The code also uses an API key from environment variables, reinforcing that this client handles sensitive access paths without disclosure.
This code receives webhook payloads and headers and emits them for downstream processing, which is a network-driven data intake path that can include user or system data. While the file has brief developer comments, it lacks any explicit user-facing warning or disclosure about handling incoming webhook data or associated headers.
The server accepts an arbitrary callbackUrl from the request body and then POSTs workflow/action/result data plus the shared X-N8N-Token to that destination. This creates an SSRF-style data exfiltration path and leaks the authentication token to attacker-controlled endpoints, which can enable further unauthorized requests to the service.
The example HTTP Request node posts workflow JSON to http://localhost:3000/webhook/trigger, but the markdown does not warn readers that this is an insecure example if adapted beyond local development. In markdown guidance, networked behaviors that may affect privacy or system integrity should be accompanied by a caution when examples could be operationalized.
Natural-language policy violations include forcing a specific language without user opt-in. This file presents all instructional content in Chinese and does not indicate that the skill is region-specific or provide an alternative language option.
The workflow emits a fixed English status/message structure, but this does not clearly amount to forcing a language policy on users. Because the file contains only minimal string literals and no explicit language requirement, this is at best a weak signal.
The lockfile pins body-parser 1.20.4, and the provided advisory indicates a denial-of-service condition related to invalid limit handling. Even though this file is only dependency metadata and not exploit code, shipping a vulnerable parser in a server-side Express stack can expose request-processing paths to resource exhaustion or crashes if the application uses body parsing on attacker-controlled input.
The qs package is present at 6.14.2 and the supplied advisories describe multiple denial-of-service and parser-bypass issues. Because qs is commonly used to parse attacker-controlled query strings and form bodies in Express applications, these flaws can be relevant if the application accepts untrusted request data, though the listed impacts are still primarily low-severity DoS or parsing edge cases.
The dependency on Express is version-ranged with a caret (^4.18.2), which allows automatic installation of newer compatible releases rather than a single fixed version. This can introduce supply-chain risk and reduce build reproducibility, especially for an integration skill that may expose webhook-facing network functionality.
"author": "yuyonghao-123",
"license": "MIT",
"dependencies": {
"express": "^4.18.2"
},
"engines": {
"node": ">=18.0.0"
This file's natural-language content, including the header documentation and runtime log messages, is written in Chinese only. Under the stated policy, forcing a specific language without user opt-in is a locale/language policy concern because the skill does not offer any alternative language choice or document a justified region-specific limitation.
The file's natural-language documentation and runtime log strings are written in Chinese, which effectively fixes the operator-facing language without any opt-in or locale selection. Under the policy, language constraints should either be optional, user-selectable, or explicitly justified as region-specific.
This JavaScript file contains natural-language strings such as the header comment and console output in Chinese, which imposes a specific language on users or maintainers reading test output. The policy allows fixed locale only when justified or when users are given a choice, neither of which is present here.
Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal