{
  "$schema": "https://docs.oasis-open.org/csaf/csaf/v2.1/schema/csaf.json",
  "document": {
    "category": "csaf_security_advisory",
    "csaf_version": "2.1",
    "distribution": {
      "tlp": {
        "label": "CLEAR"
      }
    },
    "lang": "en",
    "notes": [
      {
        "category": "summary",
        "text": "ndaal SARIF Viewer (sarif-viewer) 1.1.16 and 1.2.17 redirect the browser to an attacker-chosen host when the language switcher is called from a page whose URL contains a backslash. CVSS v3.1 4.7 (Medium), CVSS v4.0 2.1 (Low). Fixed in 1.2.18.",
        "title": "Summary"
      },
      {
        "category": "description",
        "text": "Affected: sarif-viewer 1.1.16 and 1.2.17, the releases that contain the language switcher (introduced in commit 7677b189). sarif-viewer 1.1.15 and earlier have no `/lang/{code}` route and are not affected. The language switcher is the only route of the viewer that sets a `Location` response header.",
        "title": "Scope"
      },
      {
        "category": "general",
        "text": "Upgrade to sarif-viewer 1.2.18, released on 2026-10-26 (GitLab release v1.2.18 and crates.io). The fix is in commit 2f9d8feb: a backslash anywhere in the referer path now makes the switcher fall back to `/`. Until the upgrade, drop or blank the `Referer` request header for `/lang/` requests at a reverse proxy in front of the viewer (for example `proxy_set_header Referer \"\";` in a `location /lang/` block in nginx). The switcher then always returns to `/`.",
        "title": "Recommended action"
      },
      {
        "category": "legal_disclaimer",
        "text": "THIS DOCUMENT IS PROVIDED ON AN 'AS IS' BASIS AND DOES NOT IMPLY ANY KIND OF GUARANTEE OR WARRANTY. ndaal Gesellschaft fuer Sicherheit in der Informationstechnik mbH & Co KG DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS INFORMATION INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.",
        "title": "Legal Disclaimer"
      }
    ],
    "publisher": {
      "category": "vendor",
      "contact_details": "security@ndaal.eu",
      "issuing_authority": "ndaal Gesellschaft für Sicherheit in der Informationstechnik mbH & Co KG Security Team",
      "name": "ndaal Gesellschaft für Sicherheit in der Informationstechnik mbH & Co KG",
      "namespace": "https://ndaal.eu/csaf"
    },
    "references": [
      {
        "category": "self",
        "summary": "This advisory in CSAF 2.1 format",
        "url": "https://gitlab.com/vPierre/ndaal_public_nvulnlookup/-/raw/main/csaf/2026/1104/ndaal-sa-2026-1104.json"
      },
      {
        "category": "external",
        "summary": "Fix commit 2f9d8feb",
        "url": "https://gitlab.com/vPierre/ndaal_public_sarif_viewer/-/commit/2f9d8feb"
      },
      {
        "category": "external",
        "summary": "sarif-viewer CHANGELOG",
        "url": "https://gitlab.com/vPierre/ndaal_public_sarif_viewer/-/raw/main/CHANGELOG.md"
      },
      {
        "category": "external",
        "summary": "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')",
        "url": "https://cwe.mitre.org/data/definitions/601.html"
      }
    ],
    "title": "ndaal Security Advisory: sarif-viewer open redirect in the language switcher (CWE-601)",
    "tracking": {
      "current_release_date": "2026-10-26T00:00:00.000Z",
      "generator": {
        "engine": {
          "name": "ndaal CSAF Generator",
          "version": "1.0.0"
        }
      },
      "id": "ndaal-sa-2026-1104",
      "initial_release_date": "2026-10-26T00:00:00.000Z",
      "revision_history": [
        {
          "date": "2026-10-26T00:00:00.000Z",
          "number": "1.0.0",
          "summary": "Initial advisory: open redirect in the language switcher, fixed on main (2f9d8feb) and released in 1.2.18 on 2026-10-26. Status: final."
        }
      ],
      "status": "final",
      "version": "1.0.0"
    },
    "x_extensions": [
      {
        "$schema": "https://ndaal.eu/.well-known/csaf/extensions/dashboard-branding_1.0.0.json",
        "category": "informational",
        "content": {
          "dashboard_short_name": "ndaal",
          "publisher_brand": "ndaal Advisories Database"
        },
        "critical": false
      }
    ]
  },
  "product_tree": {
    "branches": [
      {
        "branches": [
          {
            "branches": [
              {
                "category": "product_version",
                "name": "1.1.16",
                "product": {
                  "name": "ndaal SARIF Viewer (sarif-viewer) 1.1.16 - affected",
                  "product_id": "CSAFPID-0001",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@1.1.16"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "1.2.17",
                "product": {
                  "name": "ndaal SARIF Viewer (sarif-viewer) 1.2.17 - affected",
                  "product_id": "CSAFPID-0002",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@1.2.17"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "1.2.18",
                "product": {
                  "name": "ndaal SARIF Viewer (sarif-viewer) 1.2.18 - fixed",
                  "product_id": "CSAFPID-0003",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@1.2.18"
                    ]
                  }
                }
              }
            ],
            "category": "product_name",
            "name": "sarif-viewer"
          }
        ],
        "category": "vendor",
        "name": "ndaal Gesellschaft für Sicherheit in der Informationstechnik mbH & Co KG"
      }
    ]
  },
  "vulnerabilities": [
    {
      "cwes": [
        {
          "id": "CWE-601",
          "name": "URL Redirection to Untrusted Site ('Open Redirect')",
          "version": "4.13"
        }
      ],
      "discovery_date": "2026-10-26T00:00:00.000Z",
      "metrics": [
        {
          "content": {
            "cvss_v3": {
              "attackComplexity": "HIGH",
              "attackVector": "NETWORK",
              "availabilityImpact": "NONE",
              "baseScore": 4.7,
              "baseSeverity": "MEDIUM",
              "confidentialityImpact": "LOW",
              "integrityImpact": "LOW",
              "privilegesRequired": "NONE",
              "scope": "CHANGED",
              "userInteraction": "REQUIRED",
              "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N",
              "version": "3.1"
            },
            "cvss_v4": {
              "attackComplexity": "HIGH",
              "attackRequirements": "PRESENT",
              "attackVector": "NETWORK",
              "baseScore": 2.1,
              "baseSeverity": "LOW",
              "privilegesRequired": "NONE",
              "subAvailabilityImpact": "NONE",
              "subConfidentialityImpact": "LOW",
              "subIntegrityImpact": "LOW",
              "userInteraction": "ACTIVE",
              "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N",
              "version": "4.0",
              "vulnAvailabilityImpact": "NONE",
              "vulnConfidentialityImpact": "NONE",
              "vulnIntegrityImpact": "NONE"
            }
          },
          "products": [
            "CSAFPID-0001",
            "CSAFPID-0002"
          ]
        }
      ],
      "notes": [
        {
          "category": "description",
          "text": "The language switcher route `/lang/{code}` stores the chosen language and redirects the browser back to the page it came from. The target is derived from the `Referer` header by `routes::lang::return_path`, which kept only the path and query of the referer and rejected a target that starts with `//`. It did not reject a backslash. `http::Uri` accepts a backslash in the path, so a `Referer` of `https://attacker.example/\\evil.example` produced the redirect location `/\\evil.example`. Browsers treat a backslash in a `Location` value like a slash, so they read `/\\evil.example` as `//evil.example` and navigate to another host (CWE-601, URL Redirection to Untrusted Site).",
          "title": "Vulnerability description"
        },
        {
          "category": "details",
          "text": "Exploitation needs a victim who is on an attacker-controlled page and clicks a link to the viewer's `/lang/{code}` route, and a page that sends the full URL as `Referer` (for example with `Referrer-Policy: unsafe-url`; browsers trim a cross-origin referer to the origin by default, in which case the path is empty and the redirect stays on this site). The redirect then leaves a trusted origin for the host the attacker chose. The attacker does not need any access to the viewer, and the redirect carries no session data. No exploitation is known.",
          "title": "Exploitation conditions"
        },
        {
          "category": "other",
          "text": "CVSS v3.1 CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N = 4.7 (Medium): network attack vector, high attack complexity (the attacker's page must send the full referer path), no privileges, user interaction required (a click), scope changed because the browser leaves the viewer's origin, low confidentiality and integrity impact (a user can be sent to a look-alike page), no availability impact. CVSS v4.0 CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N = 2.1 (Low): high attack complexity, attack requirements present (the referrer policy of the attacker's page), active user interaction, no impact on the vulnerable system and low impact on the subsequent system. No CVSS vector is published by anyone else for this finding; both were authored here.",
          "title": "CVSS rationale"
        },
        {
          "category": "other",
          "text": "Found internally by the property test `return_path_never_leaves_this_origin` (tests/proptest_boundaries.rs), which asserts that the redirect target never starts with `//` or `/\\`; proptest shrank the failing input to `/\\`. The regression is pinned by the unit test `backslash_referer_falls_back_to_root`, the saved proptest seed and the fuzz target `fuzz_return_path`.",
          "title": "Discovery"
        }
      ],
      "product_status": {
        "fixed": [
          "CSAFPID-0003"
        ],
        "known_affected": [
          "CSAFPID-0001",
          "CSAFPID-0002"
        ]
      },
      "remediations": [
        {
          "category": "vendor_fix",
          "details": "Upgrade to sarif-viewer 1.2.18, released on 2026-10-26 (GitLab release v1.2.18 and crates.io). The fix is in commit 2f9d8feb: a backslash anywhere in the referer path now makes the switcher fall back to `/`.",
          "product_ids": [
            "CSAFPID-0001",
            "CSAFPID-0002"
          ]
        },
        {
          "category": "workaround",
          "details": "Until the upgrade, drop or blank the `Referer` request header for `/lang/` requests at a reverse proxy in front of the viewer (for example `proxy_set_header Referer \"\";` in a `location /lang/` block in nginx). The switcher then always returns to `/`.",
          "product_ids": [
            "CSAFPID-0001",
            "CSAFPID-0002"
          ]
        }
      ],
      "threats": [
        {
          "category": "impact",
          "details": "Open redirect from the viewer's origin to an attacker-chosen host.",
          "product_ids": [
            "CSAFPID-0001",
            "CSAFPID-0002"
          ]
        },
        {
          "category": "exploit_status",
          "details": "No exploitation is known.",
          "product_ids": [
            "CSAFPID-0001",
            "CSAFPID-0002"
          ]
        }
      ],
      "title": "sarif-viewer: open redirect in the language switcher through a backslash in the Referer"
    }
  ]
}