T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- workflows/03-reply-tracker.json:4
- Finding
- Unauthenticated Reply Webhook Allows Unauthorized CRM Modification and Notification Flooding<![CDATA[ ## Vulnerability Details **File Location**: `workflows/03-reply-tracker.json`, lines 4–15, 22–30, 69–127, and 137–139 **Vulnerability Type**: Missing webhook authentication and authorization **Risk Level**: High ### Vulnerable Code ```json { "parameters": { "httpMethod": "POST", "path": "outreach/reply", "responseMode": "responseNode", "options": {} }, "id": "n1", "name": "Reply Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 2 } ``` ```js const body = $input.first().json.body || $input.first().json; const email = (body.email || body.from || '').trim().toLowerCase(); const subject = (body.subject || '').trim(); const message = (body.message || body.body || '').trim(); if (!email) { return [{ json: { error: 'Email is required', valid: false } }]; } ``` ```json { "parameters": { "operation": "appendOrUpdate", "documentId": { "__rl": true, "value": "YOUR_OUTREACH_SHEET_ID", "mode": "list" }, "sheetName": { "__rl": true, "value": "Prospects", "mode": "list" }, "columns": { "mappingMode": "defineBelow", "value": { "email": "={{ $json.email }}", "replied": true, "replied_at": "={{ $json.replied_at }}", "status": "replied" }, "matchingColumns": [ "email" ] } }, "name": "Mark Replied", "type": "n8n-nodes-base.googleSheets" } ``` ```json { "parameters": { "sendTo": "={{ $env.OUTREACH_ADMIN_EMAIL || 'YOUR_NOTIFICATION_EMAIL' }}", "subject": "=Outreach Reply: {{ $json.email }}", "message": "=<h3>Reply Received</h3><p><strong>From:</strong> {{ $json.email }}</p><p><strong>Subject:</strong> {{ $json.subject }}</p><p><strong>Message:</strong></p><blockquote>{{ $json.message }}</blockquote><p><strong>Time:</strong> {{ $json.replied_at }}</p>" }, "name": "Notify Team", "type": "n8n-nodes-base.emailSend" } ``` ### Technical Analysis The `outreach/reply` webhook ...[truncated 2022 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require authentication at the webhook boundary. Prefer a cryptographically verified signature from the inbound-mail provider; otherwise, require a high-entropy shared secret in an HTTP header. 2. Validate signatures over the raw request body and use a constant-time comparison. 3. Add a timestamp and unique event identifier to reject expired or replayed requests. 4. Replace `appendOrUpdate` with an update operation that fails when the prospect does not already exist. 5. Confirm that the submitted sender matches an existing prospect before changing campaign state. 6. Apply endpoint and infrastructure rate limits, request-body size limits, and per-source throttling. 7. Return `401 Unauthorized` or `403 Forbidden` for authentication failures rather than processing the event. 8. Restrict the Google Sheets credential to only the required document and minimum necessary permissions. 9. Monitor excessive reply events, failed signature checks, and abnormal SMTP volume. ]]>
