T09 · Insecure Skill Coding Practices
- Location
templates.md:102- Finding
Shared AI Memory Fallback Enables Cross-User Context Leakage
- Content
View full analysis
Vulnerability Details
File Location:
templates.md, line 102
Vulnerability Type: Shared memory namespace caused by an insecure default session key
Risk Level: MediumComplete Code Snippet:
json { "id": "4", "name": "Memory", "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", "typeVersion": 1, "position": [550, 550], "parameters": { "sessionIdType": "customKey", "sessionKey": "={{ $json.body.sessionId ?? 'default' }}", "contextWindowLength": 20 } }Technical Analysis
The AI-agent workflow template uses a client-supplied
sessionIdas its memory key and substitutes the constant valuedefaultwhen that field is absent. Consequently, every webhook request that omitssessionIdis assigned to the same memory namespace.In a multi-user deployment, the buffer-window memory may place messages from unrelated users into one shared conversation. The template also does not demonstrate authentication, authorization, tenant binding, or server-side session-ID generation. Even when a session ID is supplied, accepting it directly from the request allows a caller to attempt session-key reuse or guessing.
This is an insecure coding/configuration practice rather than deliberate persistent agent-memory poisoning. The affected memory is workflow conversation state, and the audited material does not establish that it modifies the Skill's own long-term instructions.
Attack Path
- An operator deploys the documented AI-agent webhook template without replacing the fallback behavior.
- An attacker sends requests to the webhook while omitting
body.sessionId. - The workflow stores the attacker's messages under the shared
defaultmemory key. - A victim also sends a request without a session ID and is assigned the same key.
- The AI agent receives conversation context containing messages from both callers.
- The victim may receive information derived from the att ...[truncated 853 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove the global fallback and reject requests without a valid authenticated session identity:
javascript ={{ (() => { if (!$json.authenticatedUserId || !$json.body.sessionId) { throw new Error('Authenticated user and session ID are required'); } return `${$json.authenticatedUserId}:${$json.body.sessionId}`; })() }} -
Derive the memory key from trusted server-side authentication context rather than accepting identity solely from the webhook body.
-
Bind the key to both tenant/user identity and a high-entropy session identifier.
-
Validate the identifier's format and length, and prevent callers from selecting another user's namespace.
-
Add webhook authentication and authorization before invoking the AI agent or memory node.
-
Define retention limits and clear memory when sessions expire.
-
Avoid placing credentials or unnecessary sensitive data in conversational memory.
-
Add tests proving that requests from different users, including requests with missing or reused IDs, cannot read or influence one another's memory.
-
