id: CVE-2026-21877

info:
  name: n8n >= 0.123.0 and < 1.121.3 - Remote Code Execution
  author: s4e-io
  severity: critical
  description: |
    n8n versions >= 0.123.0 and < 1.121.3 contain a critical authenticated remote code execution vulnerability via arbitrary file write. An authenticated user can exploit the Git node to overwrite critical files and execute untrusted code on the n8n server, potentially leading to full system compromise. The vulnerability affects both self-hosted and n8n Cloud instances.
  impact: |
    Full system compromise including access to all credentials, API tokens, OAuth secrets, database connections, and workflow automation capabilities. n8n becomes a single point of failure exposing all connected systems.
  remediation: |
    Upgrade to n8n v1.121.3 or later. If upgrading is not immediately possible, disable the Git node and limit access for untrusted users.
  reference:
    - https://github.com/n8n-io/n8n/security/advisories/GHSA-v364-rw7m-3263
    - https://nvd.nist.gov/vuln/detail/CVE-2026-21877
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 9.9
    cve-id: CVE-2026-21877
    epss-score: 0.05258
    epss-percentile: 0.9148
    cwe-id: CWE-434
  metadata:
    verified: true
    max-request: 1
    vendor: n8n-io
    product: n8n
    shodan-query: http.favicon.hash:-831756631
    fofa-query: icon_hash="-831756631"
  tags: cve,cve2026,n8n,workflow,rce,authenticated,passive

http:
  - method: GET
    path:
      - "{{BaseURL}}/signin"

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "<title>n8n.io"
        case-insensitive: true

      - type: dsl
        name: vulnerable
        dsl:
          - compare_versions(version, '>= 0.123.0', '< 1.121.3')

      - type: status
        status:
          - 200

    extractors:
      - type: regex
        name: base64_content
        group: 1
        regex:
          - '<meta name="n8n:config:sentry" content="([A-Za-z0-9+/=]+)"'
        internal: true

      - type: dsl
        name: version
        dsl:
          - 'replace_regex(base64_decode(base64_content), ".*n8n@([0-9]+\\.[0-9]+\\.[0-9]+).*", "$1")'
        internal: true

      - type: dsl
        dsl:
          - '"n8n Version: " + version'
# digest: 4a0a00473045022100ca889d0fd37338814d33fc2fa84d0c1dde8ec112797fe923678cb0c4f7c4d5d2022009b3c3b0ae04ce114d77ac790c0270cef0b4f3c8716d2ed4c05ac11a298ec4e5:922c64590222798bb761d5b6d8e72950