{
  "id": "hBay3VAWzhX0w5bU",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Cybersecurity phishing attack prevention tool",
  "tags": [],
  "nodes": [
    {
      "id": "578da4c5-64c8-48ba-b7fc-82eef7c49510",
      "name": "Sticky Note Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -720,
        32
      ],
      "parameters": {
        "width": 460,
        "height": 820,
        "content": "## \ud83d\udee1\ufe0f Phishing Attack Prevention\n\nReal-time phishing detection pipeline. Ingests emails, extracts IOCs, analyzes with GPT-4, scores risk, then auto-quarantines, flags, or clears \u2014 with SOC alerts and audit logging.\n\n### Flow\n1. Webhook receives email\n2. Extract URLs, domains, keywords\n3. VirusTotal + GPT-4 analysis\n4. Risk score routing\n5. Quarantine / Flag / Allow\n6. Slack SOC alert + audit log\n\n### Risk Levels\n\ud83d\udd34 **HIGH (75\u2013100)** \u2192 Quarantine\n\ud83d\udfe1 **MEDIUM (40\u201374)** \u2192 Flag + warn\n\ud83d\udfe2 **LOW (0\u201339)** \u2192 Allow + log\n\n### Credentials\n- OpenAI API (GPT-4o)\n- VirusTotal API\n- Slack Webhook\n- Google Sheets\n- SMTP Email\n\n### Placeholders to Replace\n- `YOUR_OPENAI_CREDENTIAL_ID`\n- `YOUR_VIRUSTOTAL_API_KEY`\n- `YOUR_SLACK_WEBHOOK_PATH`\n- `YOUR_GOOGLE_SHEET_ID`\n- `YOUR_EMAIL_GATEWAY_TOKEN`"
      },
      "typeVersion": 1
    },
    {
      "id": "77892aca-d0d7-48e3-8371-0cd4a67fd090",
      "name": "Sticky Note S1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        288
      ],
      "parameters": {
        "color": 6,
        "width": 620,
        "height": 324,
        "content": "## Step 1 \u2014 Ingest & Extract IOCs"
      },
      "typeVersion": 1
    },
    {
      "id": "0007772b-b55e-476d-8959-5c492a05b0eb",
      "name": "Sticky Note S2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        112
      ],
      "parameters": {
        "color": 6,
        "width": 524,
        "height": 740,
        "content": "## Step 2 \u2014 GPT-4 Threat Analysis"
      },
      "typeVersion": 1
    },
    {
      "id": "ba55bc03-3b5b-4f0b-b39f-cf0da27a2bc0",
      "name": "Sticky Note S3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        112
      ],
      "parameters": {
        "color": 6,
        "width": 700,
        "height": 740,
        "content": "## Step 3 \u2014 Risk Routing & Actions"
      },
      "typeVersion": 1
    },
    {
      "id": "0eded51c-c82f-4967-bcce-48b47bca8582",
      "name": "Sticky Note S4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1888,
        112
      ],
      "parameters": {
        "color": 6,
        "width": 492,
        "height": 740,
        "content": "## Step 4 \u2014 Alert, Log & Respond"
      },
      "typeVersion": 1
    },
    {
      "id": "e3611d35-3fbe-4c2a-9652-1e01bda48b0d",
      "name": "Receive Email via Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -192,
        400
      ],
      "parameters": {
        "path": "phishing-check",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "d6a94b60-9ff5-4d58-bda0-dead2a4bc89f",
      "name": "Extract IOCs & Normalize",
      "type": "n8n-nodes-base.code",
      "position": [
        64,
        400
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const body = $input.item.json.body || $input.item.json;\n\nif (!body.subject && !body.emailBody) {\n  throw new Error('Email subject or body is required');\n}\n\nconst emailText = `${body.subject || ''} ${body.emailBody || body.body || ''}`;\n\n// Extract URLs\nconst urlRegex = /https?:\\/\\/[^\\s<>\"']+/gi;\nconst extractedUrls = [...new Set(emailText.match(urlRegex) || [])].slice(0, 15);\n\n// Extract domains\nconst domains = [...new Set(extractedUrls.map(url => {\n  try { return new URL(url).hostname; } catch(e) { return null; }\n}).filter(Boolean))];\n\n// Phishing keyword check\nconst phishKeywords = [\n  'urgent','verify your account','click here','update payment',\n  'suspended','confirm identity','act now','password expired',\n  'invoice attached','wire transfer','bitcoin','gift card',\n  'winner','free gift','limited offer','account compromised'\n];\nconst keywordsHit = phishKeywords.filter(kw =>\n  emailText.toLowerCase().includes(kw)\n);\n\n// Sender vs reply-to mismatch\nconst senderEmail = (body.senderEmail || body.from || '').toLowerCase();\nconst replyTo = (body.replyTo || '').toLowerCase();\nconst senderDomain = senderEmail.split('@')[1] || '';\nconst replyDomain = replyTo.split('@')[1] || '';\nconst domainMismatch = !!(replyTo && senderDomain && replyDomain && senderDomain !== replyDomain);\n\n// Suspicious attachments\nconst dangerExts = /\\.(exe|js|vbs|ps1|bat|cmd|scr|jar|zip|rar|hta)$/i;\nconst suspAttachments = (body.attachments || []).filter(a => dangerExts.test(a.filename || ''));\n\nreturn {\n  json: {\n    emailRecord: {\n      emailId: `PHISH-${Date.now()}-${Math.random().toString(36).substr(2,6).toUpperCase()}`,\n      subject: body.subject || '(No Subject)',\n      senderEmail,\n      senderName: body.senderName || '',\n      recipientEmail: body.recipientEmail || body.to || '',\n      replyTo,\n      emailBody: emailText.substring(0, 2500),\n      extractedUrls,\n      domains,\n      keywordsHit,\n      keywordCount: keywordsHit.length,\n      domainMismatch,\n      suspAttachmentCount: suspAttachments.length,\n      suspAttachmentNames: suspAttachments.map(a => a.filename),\n      receivedAt: body.receivedAt || new Date().toISOString()\n    }\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "4d93b988-ef17-4633-9828-35a8507f0b02",
      "name": "VirusTotal URL Scan",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        480,
        304
      ],
      "parameters": {
        "url": "https://www.virustotal.com/api/v3/urls",
        "method": "POST",
        "options": {
          "timeout": 12000
        },
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "formUrlEncoded",
        "headerParameters": {
          "parameters": [
            {
              "name": "x-apikey",
              "value": "YOUR_VIRUSTOTAL_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "3acafc2f-9982-4095-9e46-8dba8ac3a7d3",
      "name": "GPT-4 Phishing Analysis",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        480,
        496
      ],
      "parameters": {
        "text": "=You are an expert cybersecurity analyst specializing in phishing detection.\n\nAnalyze this email and return a structured phishing risk assessment.\n\n**Email:**\n- Subject: {{ $json.emailRecord.subject }}\n- From: {{ $json.emailRecord.senderEmail }}\n- Reply-To: {{ $json.emailRecord.replyTo || 'same as sender' }}\n- Domain Mismatch: {{ $json.emailRecord.domainMismatch }}\n- Keywords Triggered ({{ $json.emailRecord.keywordCount }}): {{ $json.emailRecord.keywordsHit.join(', ') || 'none' }}\n- URLs Found: {{ $json.emailRecord.extractedUrls.slice(0,5).join(', ') || 'none' }}\n- Suspicious Attachments: {{ $json.emailRecord.suspAttachmentCount }} \u2014 {{ $json.emailRecord.suspAttachmentNames.join(', ') || 'none' }}\n- Body: {{ $json.emailRecord.emailBody.substring(0, 1500) }}\n\n**Respond in JSON only:**\n{\n  \"riskScore\": 85,\n  \"riskLevel\": \"HIGH\",\n  \"attackType\": \"credential_phishing\",\n  \"confidenceLevel\": 91,\n  \"isPhishing\": true,\n  \"impersonatedBrand\": \"Microsoft\",\n  \"socialEngineeringTactics\": [\"urgency\", \"fear\"],\n  \"credentialHarvestingRisk\": true,\n  \"recommendation\": \"QUARANTINE\",\n  \"userWarningMessage\": \"Short plain-English warning for the recipient\",\n  \"socSummary\": \"2-sentence technical summary for SOC team\"\n}",
        "options": {
          "systemMessage": "You are a phishing detection AI. Output valid JSON only \u2014 no markdown, no preamble. When in doubt, flag as suspicious."
        },
        "promptType": "define"
      },
      "typeVersion": 1.6
    },
    {
      "id": "29042c2d-7a97-4776-a77c-9fb1b37f8ce9",
      "name": "GPT-4o Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        560,
        704
      ],
      "parameters": {
        "model": "gpt-4o",
        "options": {
          "maxTokens": 800,
          "temperature": 0.1
        }
      },
      "typeVersion": 1
    },
    {
      "id": "03ff8740-77ef-4664-9e45-c6e3ed281470",
      "name": "Parse & Score Risk",
      "type": "n8n-nodes-base.code",
      "position": [
        768,
        400
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const aiResp = $input.item.json;\nlet aiText = aiResp.response || aiResp.output || aiResp.text || '';\nif (aiResp.content && Array.isArray(aiResp.content)) {\n  aiText = aiResp.content[0]?.text || '';\n}\nconst clean = aiText.replace(/```json\\s*/g,'').replace(/```\\s*/g,'').trim();\n\nlet analysis;\ntry { analysis = JSON.parse(clean); }\ncatch(e) { throw new Error(`Parse failed: ${e.message}. Raw: ${clean.substring(0,150)}`); }\n\nconst vtResult = $('VirusTotal URL Scan').item.json;\nconst vtMalicious = vtResult?.data?.attributes?.last_analysis_stats?.malicious || 0;\nconst vtSuspicious = vtResult?.data?.attributes?.last_analysis_stats?.suspicious || 0;\n\nlet score = analysis.riskScore || 0;\nif (vtMalicious > 0) score = Math.min(100, score + 20);\nif (vtSuspicious > 0) score = Math.min(100, score + 10);\n\nconst riskLevel = score >= 75 ? 'HIGH' : score >= 40 ? 'MEDIUM' : 'LOW';\nconst action = riskLevel === 'HIGH' ? 'QUARANTINE' : riskLevel === 'MEDIUM' ? 'FLAG' : 'ALLOW';\n\nconst emailRecord = $('Extract IOCs & Normalize').item.json.emailRecord;\n\nreturn {\n  json: {\n    emailRecord,\n    analysis: { ...analysis, riskScore: score, riskLevel },\n    vtMalicious,\n    vtSuspicious,\n    riskLevel,\n    finalScore: score,\n    action,\n    analyzedAt: new Date().toISOString()\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "e4ccf4d7-2295-4dac-b3b5-4194d07652f4",
      "name": "Risk Level Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        1200,
        400
      ],
      "parameters": {
        "mode": "expression"
      },
      "typeVersion": 3
    },
    {
      "id": "6b88bc07-8306-42a5-907e-dbe665011f7b",
      "name": "Quarantine \u2014 HIGH",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1440,
        256
      ],
      "parameters": {
        "url": "https://YOUR_EMAIL_GATEWAY_API/v1/emails/quarantine",
        "method": "POST",
        "options": {
          "timeout": 10000
        },
        "jsonBody": "={\"emailId\":\"{{ $json.emailRecord.emailId }}\",\"action\":\"quarantine\",\"riskScore\":{{ $json.finalScore }},\"attackType\":\"{{ $json.analysis.attackType }}\",\"recipient\":\"{{ $json.emailRecord.recipientEmail }}\"}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "83b2a738-f67b-4837-a741-c63c72ac34cc",
      "name": "Flag \u2014 MEDIUM",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1440,
        416
      ],
      "parameters": {
        "url": "https://YOUR_EMAIL_GATEWAY_API/v1/emails/flag",
        "method": "POST",
        "options": {
          "timeout": 10000
        },
        "jsonBody": "={\"emailId\":\"{{ $json.emailRecord.emailId }}\",\"action\":\"flag_suspicious\",\"riskScore\":{{ $json.finalScore }},\"recipient\":\"{{ $json.emailRecord.recipientEmail }}\"}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "bb2e3f3b-9e6f-46f6-9431-413620326381",
      "name": "Allow \u2014 LOW",
      "type": "n8n-nodes-base.set",
      "position": [
        1440,
        576
      ],
      "parameters": {
        "options": {},
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "983c2a98-b5f1-4bce-a38c-70664b919916",
      "name": "Merge All Paths",
      "type": "n8n-nodes-base.merge",
      "position": [
        1680,
        416
      ],
      "parameters": {
        "mode": "mergeByPosition"
      },
      "typeVersion": 3
    },
    {
      "id": "1d05e27f-e295-4ebe-be66-9576268d4a1e",
      "name": "Slack SOC Alert",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1936,
        272
      ],
      "parameters": {
        "url": "https://hooks.slack.com/services/YOUR_SLACK_WEBHOOK_PATH",
        "method": "POST",
        "options": {
          "timeout": 8000
        },
        "jsonBody": "={\n  \"channel\": \"#soc-phishing\",\n  \"username\": \"PhishBot\",\n  \"icon_emoji\": \":rotating_light:\",\n  \"blocks\": [\n    {\n      \"type\": \"header\",\n      \"text\": { \"type\": \"plain_text\", \"text\": \"{{ $json.riskLevel === 'HIGH' ? '\ud83d\udea8 PHISHING QUARANTINED' : '\u26a0\ufe0f SUSPICIOUS EMAIL FLAGGED' }}\", \"emoji\": true }\n    },\n    {\n      \"type\": \"section\",\n      \"fields\": [\n        { \"type\": \"mrkdwn\", \"text\": \"*Risk Score:*\\n{{ $json.finalScore }}/100\" },\n        { \"type\": \"mrkdwn\", \"text\": \"*Attack Type:*\\n{{ $json.analysis.attackType }}\" },\n        { \"type\": \"mrkdwn\", \"text\": \"*Action:*\\n{{ $json.action }}\" },\n        { \"type\": \"mrkdwn\", \"text\": \"*Sender:*\\n{{ $json.emailRecord.senderEmail }}\" },\n        { \"type\": \"mrkdwn\", \"text\": \"*Impersonated:*\\n{{ $json.analysis.impersonatedBrand || 'None' }}\" },\n        { \"type\": \"mrkdwn\", \"text\": \"*VT Hits:*\\n{{ $json.vtMalicious }} malicious\" }\n      ]\n    },\n    {\n      \"type\": \"section\",\n      \"text\": { \"type\": \"mrkdwn\", \"text\": \"*SOC Summary:*\\n{{ $json.analysis.socSummary }}\" }\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "c80d2b0e-71a2-4915-892e-8c6ce0fe7a67",
      "name": "Warn User via Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1936,
        480
      ],
      "parameters": {
        "options": {},
        "subject": "=[Security Alert] {{ $json.riskLevel === 'HIGH' ? 'Phishing email quarantined' : 'Suspicious email flagged' }} \u2014 {{ $json.emailRecord.subject }}",
        "toEmail": "=",
        "fromEmail": "="
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1,
      "continueOnFail": true
    },
    {
      "id": "2768a6ba-9a9a-4362-9533-0ae837567dc9",
      "name": "Write Audit Log",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1936,
        672
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "="
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "="
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5,
      "continueOnFail": true
    },
    {
      "id": "de5a742d-6eed-4a16-b39e-09a67b893b72",
      "name": "Return Detection Result",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        2208,
        480
      ],
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "application/json"
              },
              {
                "name": "X-Risk-Level",
                "value": "={{ $json.riskLevel }}"
              },
              {
                "name": "X-Risk-Score",
                "value": "={{ $json.finalScore }}"
              }
            ]
          }
        },
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ emailId: $json.emailRecord.emailId, riskLevel: $json.riskLevel, riskScore: $json.finalScore, action: $json.action, attackType: $json.analysis.attackType, isPhishing: $json.analysis.isPhishing, analyzedAt: $json.analyzedAt }) }}"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "28a1307b-2b62-47ca-bb88-fcb27e166fc4",
  "connections": {
    "GPT-4o Model": {
      "ai_languageModel": [
        [
          {
            "node": "GPT-4 Phishing Analysis",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Allow \u2014 LOW": {
      "main": [
        [
          {
            "node": "Merge All Paths",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Flag \u2014 MEDIUM": {
      "main": [
        [
          {
            "node": "Merge All Paths",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge All Paths": {
      "main": [
        [
          {
            "node": "Slack SOC Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Warn User via Email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Write Audit Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack SOC Alert": {
      "main": [
        [
          {
            "node": "Return Detection Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write Audit Log": {
      "main": [
        [
          {
            "node": "Return Detection Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Risk Level Switch": {
      "main": [
        [
          {
            "node": "Quarantine \u2014 HIGH",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Flag \u2014 MEDIUM",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Allow \u2014 LOW",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Score Risk": {
      "main": [
        [
          {
            "node": "Risk Level Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Quarantine \u2014 HIGH": {
      "main": [
        [
          {
            "node": "Merge All Paths",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "VirusTotal URL Scan": {
      "main": [
        [
          {
            "node": "Parse & Score Risk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Warn User via Email": {
      "main": [
        [
          {
            "node": "Return Detection Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GPT-4 Phishing Analysis": {
      "main": [
        [
          {
            "node": "Parse & Score Risk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract IOCs & Normalize": {
      "main": [
        [
          {
            "node": "VirusTotal URL Scan",
            "type": "main",
            "index": 0
          },
          {
            "node": "GPT-4 Phishing Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive Email via Webhook": {
      "main": [
        [
          {
            "node": "Extract IOCs & Normalize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}