csaf_ndaal:ndaal-sa-2026-647

MEDIUM csaf_ndaal
Description

ndaal SARIF Viewer 0.1.0 through 1.1.12 built the HTTP/3 response head from the response status alone, so responses served over QUIC carried none of the security headers the HTTP/1.1 and HTTP/2 responses carried — including Content-Security-Policy, X-Frame-Options, Strict-Transport-Security, X-Content-Type-Options and Content-Type. Fixed in 1.1.13. NOT exploitable as deployed: the QUIC listener is loopback-bound by default and was not exposed to the Internet, so the vector is AV:L. CVSS v3.1 base score 4.4 (MEDIUM).

Timeline
Published
2026-09-17 12:00 UTC
Last Modified
2026-09-17
CVSS Details

CVSS details not available.

Affected Products

No product information available.

Weaknesses (CWE)
References

No references available.

Linked Vulnerabilities

No linked vulnerabilities found.

{
  "$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 0.1.0 through 1.1.12 built the HTTP/3 response head from the response status alone, so responses served over QUIC carried none of the security headers the HTTP/1.1 and HTTP/2 responses carried — including Content-Security-Policy, X-Frame-Options, Strict-Transport-Security, X-Content-Type-Options and Content-Type. Fixed in 1.1.13. NOT exploitable as deployed: the QUIC listener is loopback-bound by default and was not exposed to the Internet, so the vector is AV:L. CVSS v3.1 base score 4.4 (MEDIUM).",
        "title": "Summary"
      },
      {
        "category": "description",
        "text": "The HTTP/3 response head was constructed from the response status alone, so every header the router had produced was discarded before the response left the QUIC listener. A request answered over HTTP/3 therefore carried no Content-Security-Policy, no X-Frame-Options, no Strict-Transport-Security, no X-Content-Type-Options, no Referrer-Policy, no Permissions-Policy, none of the three cross-origin isolation headers, and no Content-Type — while the identical request over HTTP/1.1 or HTTP/2 carried all of them. For a client speaking HTTP/3 the clickjacking, MIME-sniffing and cross-origin isolation mitigations were absent, and the Content-Security-Policy that would contain a future cross-site scripting defect was not applied. Measured against a live listener with an HTTP/3-capable client rather than inferred from the source: 0 header lines over QUIC against 14 over TCP before the fix, and 13 over QUIC after it. The viewer's own output escaping — HTML metacharacter escaping and Unicode bidi/format-control neutralisation (CVE-2021-42574 class) — was NOT affected and remained effective on both transports, which is why this is a loss of a defence-in-depth layer rather than a directly exploitable flaw.",
        "title": "Impact"
      },
      {
        "category": "general",
        "text": "NOT EXPLOITABLE AS DEPLOYED. The QUIC/UDP listener binds the loopback interface (127.0.0.1) by default, exactly as the HTTPS/TCP listener does, and it was not exposed to the Internet. Reaching the affected listener therefore requires local access to the host, which is why the CVSS vector below records AV:L rather than AV:N. Two further conditions narrow it further: a client must actually negotiate HTTP/3 to the QUIC port (browsers do not switch to QUIC for a direct https://host:port navigation, and reach it only by following the Alt-Svc advertisement), and an analyst must open a document in the viewer. For reference, the same defect on an Internet-exposed listener would score CVSS v3.1 5.4 (AV:N) rather than 4.4. No exploitation has been observed, and none is believed to have been possible in any ndaal deployment.",
        "title": "Exposure and exploitability"
      },
      {
        "category": "general",
        "text": "AV:L records that the QUIC listener is loopback-bound by default and was not Internet-exposed (see the Exposure note). UI:R records that an analyst must view a document over HTTP/3. C:L / I:L record the loss of a defence-in-depth layer — the absent Content-Security-Policy, X-Frame-Options and X-Content-Type-Options would have contained a clickjacking or MIME-confusion attempt — rather than a demonstrated compromise, because the viewer's own escaping remained effective. A:N: availability is unaffected. CVSS v3.1 base score 4.4 (MEDIUM), vector CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N. CVSS v4.0 base score 4.8 (MEDIUM), vector CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N.",
        "title": "CVSS Scoring Rationale"
      },
      {
        "category": "general",
        "text": "Why the defect survived four independent test layers, recorded so the gap is not reopened: the Bruno HTTP collection speaks HTTP/1.1 and HTTP/2 only; the Playwright browser suite runs Chromium, which does not switch to QUIC for a direct https://host:port navigation; the Rust route-sequence integration test drives the router's request handler directly, where the headers ARE still present, because the loss occurred in the HTTP/3 transport layer beneath it; and the security spec asserted only that HTTP/3 was ADVERTISED via Alt-Svc, never that an HTTP/3 response was hardened. Every layer reported green while the protocol was unprotected. The fix extracts the head construction into a testable function and adds four unit tests, including one asserting that repeated header values are not collapsed.",
        "title": "Why it went undetected"
      },
      {
        "category": "general",
        "text": "sarif-viewer is a secure, memory-safe, single-binary offline viewer, validator and multi-format exporter for SARIF 2.1.0 and SARIF 2.2 (draft). It serves an embedded UI over a TLS 1.3 listener (rustls with the aws-lc-rs provider and prefer-post-quantum key exchange) that speaks HTTP/1.1 and HTTP/2 over TCP and, unless disabled with --no-quic, HTTP/3 over QUIC/UDP. Both listeners bind 127.0.0.1 by default.",
        "title": "Product Description"
      },
      {
        "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_csaf_information/-/raw/main/csaf/2026/647/ndaal-sa-2026-647.json"
      },
      {
        "category": "external",
        "summary": "sarif-viewer source code",
        "url": "https://gitlab.com/vPierre/ndaal_public_sarif_viewer"
      },
      {
        "category": "external",
        "summary": "sarif-viewer on crates.io",
        "url": "https://crates.io/crates/sarif-viewer"
      },
      {
        "category": "external",
        "summary": "RFC 9114 (HTTP/3) section 4.2 — connection-specific header fields",
        "url": "https://www.rfc-editor.org/rfc/rfc9114.html#section-4.2"
      },
      {
        "category": "external",
        "summary": "OWASP Secure Headers Project",
        "url": "https://owasp.org/www-project-secure-headers/"
      }
    ],
    "title": "ndaal Security Advisory: HTTP/3 responses served without security headers in sarif-viewer 0.1.0 through 1.1.12",
    "tracking": {
      "current_release_date": "2026-09-17T12:00:00.000Z",
      "generator": {
        "engine": {
          "name": "ndaal CSAF Generator",
          "version": "1.0.0"
        }
      },
      "id": "ndaal-sa-2026-647",
      "initial_release_date": "2026-09-17T12:00:00.000Z",
      "revision_history": [
        {
          "date": "2026-09-17T12:00:00.000Z",
          "number": "1.0.0",
          "summary": "HTTP/3 responses served without the security-header set; fixed in 1.1.13. Not exploitable as deployed (loopback-bound QUIC)."
        }
      ],
      "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": "0.1.0",
                "product": {
                  "name": "ndaal SARIF Viewer 0.1.0",
                  "product_id": "CSAFPID-0001",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@0.1.0"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "0.1.1",
                "product": {
                  "name": "ndaal SARIF Viewer 0.1.1",
                  "product_id": "CSAFPID-0002",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@0.1.1"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "0.1.2",
                "product": {
                  "name": "ndaal SARIF Viewer 0.1.2",
                  "product_id": "CSAFPID-0003",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@0.1.2"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "0.1.3",
                "product": {
                  "name": "ndaal SARIF Viewer 0.1.3",
                  "product_id": "CSAFPID-0004",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@0.1.3"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "0.1.4",
                "product": {
                  "name": "ndaal SARIF Viewer 0.1.4",
                  "product_id": "CSAFPID-0005",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@0.1.4"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "0.1.5",
                "product": {
                  "name": "ndaal SARIF Viewer 0.1.5",
                  "product_id": "CSAFPID-0006",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@0.1.5"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "0.1.6",
                "product": {
                  "name": "ndaal SARIF Viewer 0.1.6",
                  "product_id": "CSAFPID-0007",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@0.1.6"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "0.1.7",
                "product": {
                  "name": "ndaal SARIF Viewer 0.1.7",
                  "product_id": "CSAFPID-0008",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@0.1.7"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "1.1.9",
                "product": {
                  "name": "ndaal SARIF Viewer 1.1.9",
                  "product_id": "CSAFPID-0009",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@1.1.9"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "1.1.10",
                "product": {
                  "name": "ndaal SARIF Viewer 1.1.10",
                  "product_id": "CSAFPID-0010",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@1.1.10"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "1.1.11",
                "product": {
                  "name": "ndaal SARIF Viewer 1.1.11",
                  "product_id": "CSAFPID-0011",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@1.1.11"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "1.1.12",
                "product": {
                  "name": "ndaal SARIF Viewer 1.1.12",
                  "product_id": "CSAFPID-0012",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@1.1.12"
                    ]
                  }
                }
              },
              {
                "category": "product_version",
                "name": "1.1.13",
                "product": {
                  "name": "ndaal SARIF Viewer 1.1.13",
                  "product_id": "CSAFPID-0013",
                  "product_identification_helper": {
                    "purls": [
                      "pkg:cargo/sarif-viewer@1.1.13"
                    ]
                  }
                }
              }
            ],
            "category": "product_name",
            "name": "sarif-viewer"
          }
        ],
        "category": "vendor",
        "name": "ndaal Gesellschaft für Sicherheit in der Informationstechnik mbH & Co KG"
      }
    ]
  },
  "vulnerabilities": [
    {
      "cwes": [
        {
          "id": "CWE-693",
          "name": "Protection Mechanism Failure",
          "version": "4.18"
        },
        {
          "id": "CWE-1021",
          "name": "Improper Restriction of Rendered UI Layers or Frames",
          "version": "4.18"
        }
      ],
      "ids": [
        {
          "system_name": "ndaal Advisory ID",
          "text": "ndaal-sa-2026-647"
        }
      ],
      "metrics": [
        {
          "content": {
            "cvss_v3": {
              "attackComplexity": "LOW",
              "attackVector": "LOCAL",
              "availabilityImpact": "NONE",
              "baseScore": 4.4,
              "baseSeverity": "MEDIUM",
              "confidentialityImpact": "LOW",
              "integrityImpact": "LOW",
              "privilegesRequired": "NONE",
              "scope": "UNCHANGED",
              "userInteraction": "REQUIRED",
              "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N",
              "version": "3.1"
            },
            "cvss_v4": {
              "attackComplexity": "LOW",
              "attackRequirements": "NONE",
              "attackVector": "LOCAL",
              "baseScore": 4.8,
              "baseSeverity": "MEDIUM",
              "privilegesRequired": "NONE",
              "subAvailabilityImpact": "NONE",
              "subConfidentialityImpact": "NONE",
              "subIntegrityImpact": "NONE",
              "userInteraction": "PASSIVE",
              "vectorString": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N",
              "version": "4.0",
              "vulnAvailabilityImpact": "NONE",
              "vulnConfidentialityImpact": "LOW",
              "vulnIntegrityImpact": "LOW"
            }
          },
          "products": [
            "CSAFPID-0001",
            "CSAFPID-0002",
            "CSAFPID-0003",
            "CSAFPID-0004",
            "CSAFPID-0005",
            "CSAFPID-0006",
            "CSAFPID-0007",
            "CSAFPID-0008",
            "CSAFPID-0009",
            "CSAFPID-0010",
            "CSAFPID-0011",
            "CSAFPID-0012"
          ]
        }
      ],
      "notes": [
        {
          "category": "summary",
          "text": "ndaal SARIF Viewer 0.1.0 through 1.1.12 built the HTTP/3 response head from the response status alone, so responses served over QUIC carried none of the security headers the HTTP/1.1 and HTTP/2 responses carried — including Content-Security-Policy, X-Frame-Options, Strict-Transport-Security, X-Content-Type-Options and Content-Type. Fixed in 1.1.13. NOT exploitable as deployed: the QUIC listener is loopback-bound by default and was not exposed to the Internet, so the vector is AV:L. CVSS v3.1 base score 4.4 (MEDIUM).",
          "title": "Summary"
        },
        {
          "category": "description",
          "text": "The HTTP/3 response head was constructed from the response status alone, so every header the router had produced was discarded before the response left the QUIC listener. A request answered over HTTP/3 therefore carried no Content-Security-Policy, no X-Frame-Options, no Strict-Transport-Security, no X-Content-Type-Options, no Referrer-Policy, no Permissions-Policy, none of the three cross-origin isolation headers, and no Content-Type — while the identical request over HTTP/1.1 or HTTP/2 carried all of them. For a client speaking HTTP/3 the clickjacking, MIME-sniffing and cross-origin isolation mitigations were absent, and the Content-Security-Policy that would contain a future cross-site scripting defect was not applied. Measured against a live listener with an HTTP/3-capable client rather than inferred from the source: 0 header lines over QUIC against 14 over TCP before the fix, and 13 over QUIC after it. The viewer's own output escaping — HTML metacharacter escaping and Unicode bidi/format-control neutralisation (CVE-2021-42574 class) — was NOT affected and remained effective on both transports, which is why this is a loss of a defence-in-depth layer rather than a directly exploitable flaw.",
          "title": "Impact"
        },
        {
          "category": "description",
          "text": "NOT EXPLOITABLE AS DEPLOYED. The QUIC/UDP listener binds the loopback interface (127.0.0.1) by default, exactly as the HTTPS/TCP listener does, and it was not exposed to the Internet. Reaching the affected listener therefore requires local access to the host, which is why the CVSS vector below records AV:L rather than AV:N. Two further conditions narrow it further: a client must actually negotiate HTTP/3 to the QUIC port (browsers do not switch to QUIC for a direct https://host:port navigation, and reach it only by following the Alt-Svc advertisement), and an analyst must open a document in the viewer. For reference, the same defect on an Internet-exposed listener would score CVSS v3.1 5.4 (AV:N) rather than 4.4. No exploitation has been observed, and none is believed to have been possible in any ndaal deployment.",
          "title": "Exposure and exploitability"
        },
        {
          "category": "description",
          "text": "AV:L records that the QUIC listener is loopback-bound by default and was not Internet-exposed (see the Exposure note). UI:R records that an analyst must view a document over HTTP/3. C:L / I:L record the loss of a defence-in-depth layer — the absent Content-Security-Policy, X-Frame-Options and X-Content-Type-Options would have contained a clickjacking or MIME-confusion attempt — rather than a demonstrated compromise, because the viewer's own escaping remained effective. A:N: availability is unaffected. CVSS v3.1 base score 4.4 (MEDIUM), vector CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N. CVSS v4.0 base score 4.8 (MEDIUM), vector CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N.",
          "title": "CVSS Scoring Rationale"
        },
        {
          "category": "details",
          "text": "Why the defect survived four independent test layers, recorded so the gap is not reopened: the Bruno HTTP collection speaks HTTP/1.1 and HTTP/2 only; the Playwright browser suite runs Chromium, which does not switch to QUIC for a direct https://host:port navigation; the Rust route-sequence integration test drives the router's request handler directly, where the headers ARE still present, because the loss occurred in the HTTP/3 transport layer beneath it; and the security spec asserted only that HTTP/3 was ADVERTISED via Alt-Svc, never that an HTTP/3 response was hardened. Every layer reported green while the protocol was unprotected. The fix extracts the head construction into a testable function and adds four unit tests, including one asserting that repeated header values are not collapsed.",
          "title": "Why it went undetected"
        }
      ],
      "product_status": {
        "fixed": [
          "CSAFPID-0013"
        ],
        "known_affected": [
          "CSAFPID-0001",
          "CSAFPID-0002",
          "CSAFPID-0003",
          "CSAFPID-0004",
          "CSAFPID-0005",
          "CSAFPID-0006",
          "CSAFPID-0007",
          "CSAFPID-0008",
          "CSAFPID-0009",
          "CSAFPID-0010",
          "CSAFPID-0011",
          "CSAFPID-0012"
        ]
      },
      "references": [
        {
          "category": "external",
          "summary": "RFC 9114 (HTTP/3) section 4.2 — connection-specific header fields",
          "url": "https://www.rfc-editor.org/rfc/rfc9114.html#section-4.2"
        },
        {
          "category": "external",
          "summary": "OWASP Secure Headers Project",
          "url": "https://owasp.org/www-project-secure-headers/"
        }
      ],
      "remediations": [
        {
          "category": "vendor_fix",
          "details": "Upgrade to ndaal SARIF Viewer 1.1.13, which builds the HTTP/3 response head from the router's response and copies every header. Note for anyone reading this before the release lands: the fix is committed in the 1.1.13 development line (commit 12fddad7) and 1.1.13 was not yet published at the time of writing.",
          "product_ids": [
            "CSAFPID-0001",
            "CSAFPID-0002",
            "CSAFPID-0003",
            "CSAFPID-0004",
            "CSAFPID-0005",
            "CSAFPID-0006",
            "CSAFPID-0007",
            "CSAFPID-0008",
            "CSAFPID-0009",
            "CSAFPID-0010",
            "CSAFPID-0011",
            "CSAFPID-0012"
          ]
        },
        {
          "category": "workaround",
          "details": "Start the viewer with --no-quic. That disables the HTTP/3 (QUIC) listener entirely, so every response is served over HTTP/1.1 or HTTP/2 with the complete security-header set. The Alt-Svc advertisement is also suppressed, so no client is directed to HTTP/3. This is a complete mitigation and costs only the HTTP/3 transport.",
          "product_ids": [
            "CSAFPID-0001",
            "CSAFPID-0002",
            "CSAFPID-0003",
            "CSAFPID-0004",
            "CSAFPID-0005",
            "CSAFPID-0006",
            "CSAFPID-0007",
            "CSAFPID-0008",
            "CSAFPID-0009",
            "CSAFPID-0010",
            "CSAFPID-0011",
            "CSAFPID-0012"
          ]
        }
      ],
      "threats": [
        {
          "category": "impact",
          "details": "Not exploitable in any ndaal deployment. The QUIC listener binds 127.0.0.1 by default and was never exposed to the Internet, so an attacker requires local access to the host; a client must then negotiate HTTP/3 to the QUIC port, and an analyst must open a document in the viewer. No exploitation has been observed.",
          "product_ids": [
            "CSAFPID-0001",
            "CSAFPID-0002",
            "CSAFPID-0003",
            "CSAFPID-0004",
            "CSAFPID-0005",
            "CSAFPID-0006",
            "CSAFPID-0007",
            "CSAFPID-0008",
            "CSAFPID-0009",
            "CSAFPID-0010",
            "CSAFPID-0011",
            "CSAFPID-0012"
          ]
        }
      ],
      "title": "HTTP/3 response head built from the status alone, dropping the security-header set (Content-Security-Policy, X-Frame-Options, Strict-Transport-Security, X-Content-Type-Options and Content-Type)"
    }
  ]
}
View JSON API Download JSON