Raw JSON
{
"$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": "Releases up to and including 1.6.53 bundled h2 0.4.15, which accepted and queued empty HTTP/2 DATA frames without limit. A peer that opened a stream and sent empty DATA frames the application did not drain could grow the process's memory without bound, or trigger a panic if the queued length overflowed. h2 reaches the shipped binary through hyper -- the HTTP server itself -- so the runtime listener was affected, not merely the test-only dependency.",
"title": "Summary"
},
{
"category": "details",
"text": "1.6.54 pins h2 0.4.16, the upstream patched release. Verified rather than assumed: the fix was caught by the cargo-deny advisories gate inside create_release_on_crates.io.sh, which REFUSED the first publish attempt of 1.6.54; after the bump both publish gates (cargo deny check and cargo audit) return 0, and the crates.io verify build compiled h2 v0.4.16. All six release binaries were rebuilt against the fixed lockfile and every one of the six SHA-256 hashes changed, which is what demonstrates the new h2 was linked rather than a cached artifact restaged. OPERATOR NOTE, STATED PLAINLY: the v1.6.54 tag initially pointed at a build made against h2 0.4.15 and was force-updated to the rebuilt commit; that vulnerable build was never published to crates.io and no GitLab release referenced it, but its objects remain reachable in main's history. Anyone who fetched the tag in that window should re-fetch. No configuration change is available as a workaround -- upgrade is the only remediation, because the queueing happens inside the HTTP/2 implementation.",
"title": "Remediation"
},
{
"category": "general",
"text": "Upgrade to grundschutz-oscal-viewer 1.6.54 or later, which bundles h2 0.4.16. Operators who cannot upgrade immediately can reduce exposure by keeping the listener on its default loopback bind, or by terminating HTTP/2 at a reverse proxy that caps per-stream frame queueing -- neither removes the defect from the binary.",
"title": "Recommended Action"
},
{
"category": "general",
"text": "Discovered by ndaal's own OWASP ASVS v5.0.0 audit of grundschutz-oscal-viewer on 2026-08-13, which produced the product's first STRIDE threat model; this defect is recorded there as W-D1. No external report, CVE or RUSTSEC advisory exists for it.",
"title": "Discovery"
},
{
"category": "general",
"text": "grundschutz-oscal-viewer is a secure, memory-safe, single-binary offline viewer for the BSI Grundschutz++ OSCAL catalog — embedded catalog data, filters and full-text search served over a TLS 1.3 (rustls) HTTP/1.1 + HTTP/2 listener, with an annotations workspace offering optional XChaCha20-Poly1305 encryption-at-rest and embedded SQLite storage.",
"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/434/ndaal-sa-2026-434.json"
},
{
"category": "external",
"summary": "grundschutz-oscal-viewer source code",
"url": "https://gitlab.com/vPierre/ndaal_public_bsi_grundschutz_oscal_viewer"
},
{
"category": "external",
"summary": "grundschutz-oscal-viewer on crates.io",
"url": "https://crates.io/crates/grundschutz-oscal-viewer"
}
],
"title": "ndaal Security Advisory: Bundled h2 accepted unbounded empty HTTP/2 DATA frames (RUSTSEC-2026-0258) (grundschutz-oscal-viewer < 1.6.54)",
"tracking": {
"current_release_date": "2026-08-19T12:00:00.000Z",
"generator": {
"engine": {
"name": "ndaal CSAF Generator",
"version": "1.0.0"
}
},
"id": "ndaal-sa-2026-434",
"initial_release_date": "2026-08-19T12:00:00.000Z",
"revision_history": [
{
"date": "2026-08-19T12:00:00.000Z",
"number": "1.0.0",
"summary": "Initial advisory: W-D1 remediated in grundschutz-oscal-viewer 1.6.54."
}
],
"status": "final",
"version": "1.0.0"
}
},
"product_tree": {
"branches": [
{
"category": "vendor",
"name": "ndaal Gesellschaft für Sicherheit in der Informationstechnik mbH & Co KG",
"branches": [
{
"category": "product_name",
"name": "grundschutz-oscal-viewer",
"branches": [
{
"category": "product_version",
"name": "1.6.53",
"product": {
"name": "ndaal Grundschutz++ OSCAL Viewer 1.6.53",
"product_id": "CSAFPID-0001"
}
},
{
"category": "product_version",
"name": "1.6.54",
"product": {
"name": "ndaal Grundschutz++ OSCAL Viewer 1.6.54",
"product_id": "CSAFPID-0002"
}
}
]
}
]
}
]
},
"vulnerabilities": [
{
"ids": [
{
"system_name": "ndaal Grundschutz++ OSCAL Viewer threat model",
"text": "W-D1"
}
],
"notes": [
{
"category": "description",
"text": "RUSTSEC-2026-0258 (2026-08-17, alias GHSA-q83h-524g-xf6h) records the upstream flaw in the h2 crate: empty DATA frames were accepted and queued with no cap. The viewer does not implement HTTP/2 framing itself; it inherits the defect from hyper, which depends on h2 for its HTTP/2 support, and the viewer's TCP listener negotiates h2 via ALPN by default. The affected range was established by reading the lockfiles the releases actually shipped rather than assumed: v1.6.50, v1.6.52 and v1.6.53 each pin h2 0.4.15. Upstream publishes NO CVSS vector for this advisory -- it states 'Low severity' in prose only -- so the vectors here are derived and the reasoning is recorded in the generator: network-reachable (AV:N) with no credentials or interaction (PR:N/UI:N), but high attack complexity (AC:H) because the flaw only manifests when streams are not actively drained, a usage condition the attacker does not control. Data is neither disclosed nor altered (C:N/I:N); the impact is availability alone (A:L). CVSS 3.1 scores that 3.7 LOW, agreeing with upstream. CVSS 4.0 scores the same shape 6.3 MEDIUM because 4.0 weights availability-only denial of service more heavily; both figures are published rather than reconciled to one. Mapped to CWE-770 (Allocation of Resources Without Limits or Throttling), which is the precise defect class and a permitted mapping target. Threat model W-D1 ('Request flooding exhausts connections or CPU') is the row this falls under; the pre-existing mitigations there -- loopback-only default bind, the concurrency permit, and body size caps -- bound a flooding attack but do NOT bound per-stream frame queueing inside the HTTP/2 implementation, which is why the dependency bump was required rather than a configuration change.",
"title": "Description"
},
{
"category": "details",
"text": "1.6.54 pins h2 0.4.16, the upstream patched release. Verified rather than assumed: the fix was caught by the cargo-deny advisories gate inside create_release_on_crates.io.sh, which REFUSED the first publish attempt of 1.6.54; after the bump both publish gates (cargo deny check and cargo audit) return 0, and the crates.io verify build compiled h2 v0.4.16. All six release binaries were rebuilt against the fixed lockfile and every one of the six SHA-256 hashes changed, which is what demonstrates the new h2 was linked rather than a cached artifact restaged. OPERATOR NOTE, STATED PLAINLY: the v1.6.54 tag initially pointed at a build made against h2 0.4.15 and was force-updated to the rebuilt commit; that vulnerable build was never published to crates.io and no GitLab release referenced it, but its objects remain reachable in main's history. Anyone who fetched the tag in that window should re-fetch. No configuration change is available as a workaround -- upgrade is the only remediation, because the queueing happens inside the HTTP/2 implementation. CVSS v3.1 base score 3.7 (LOW), vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L. CVSS v4.0 base score 6.3 (MEDIUM), vector CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N.",
"title": "Remediation Detail"
}
],
"product_status": {
"known_affected": [
"CSAFPID-0001"
],
"fixed": [
"CSAFPID-0002"
]
},
"remediations": [
{
"category": "vendor_fix",
"details": "Upgrade to grundschutz-oscal-viewer 1.6.54 or later, which bundles h2 0.4.16. Operators who cannot upgrade immediately can reduce exposure by keeping the listener on its default loopback bind, or by terminating HTTP/2 at a reverse proxy that caps per-stream frame queueing -- neither removes the defect from the binary.",
"product_ids": [
"CSAFPID-0002"
]
}
],
"metrics": [
{
"content": {
"cvss_v3": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L",
"baseScore": 3.7,
"baseSeverity": "LOW",
"attackVector": "NETWORK",
"attackComplexity": "HIGH",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "NONE",
"integrityImpact": "NONE",
"availabilityImpact": "LOW"
},
"cvss_v4": {
"version": "4.0",
"vectorString": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"attackVector": "NETWORK",
"attackComplexity": "HIGH",
"attackRequirements": "NONE",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnAvailabilityImpact": "LOW",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"subAvailabilityImpact": "NONE"
}
},
"products": [
"CSAFPID-0001"
]
}
],
"threats": [
{
"category": "impact",
"details": "RUSTSEC-2026-0258 (2026-08-17, alias GHSA-q83h-524g-xf6h) records the upstream flaw in the h2 crate: empty DATA frames were accepted and queued with no cap. The viewer does not implement HTTP/2 framing itself; it inherits the defect from hyper, which depends on h2 for its HTTP/2 support, and the viewer's TCP listener negotiates h2 via ALPN by default. The affected range was established by reading the lockfiles the releases actually shipped rather than assumed: v1.6.50, v1.6.52 and v1.6.53 each pin h2 0.4.15. Upstream publishes NO CVSS vector for this advisory -- it states 'Low severity' in prose only -- so the vectors here are derived and the reasoning is recorded in the generator: network-reachable (AV:N) with no credentials or interaction (PR:N/UI:N), but high attack complexity (AC:H) because the flaw only manifests when streams are not actively drained, a usage condition the attacker does not control. Data is neither disclosed nor altered (C:N/I:N); the impact is availability alone (A:L). CVSS 3.1 scores that 3.7 LOW, agreeing with upstream. CVSS 4.0 scores the same shape 6.3 MEDIUM because 4.0 weights availability-only denial of service more heavily; both figures are published rather than reconciled to one. Mapped to CWE-770 (Allocation of Resources Without Limits or Throttling), which is the precise defect class and a permitted mapping target. Threat model W-D1 ('Request flooding exhausts connections or CPU') is the row this falls under; the pre-existing mitigations there -- loopback-only default bind, the concurrency permit, and body size caps -- bound a flooding attack but do NOT bound per-stream frame queueing inside the HTTP/2 implementation, which is why the dependency bump was required rather than a configuration change.",
"product_ids": [
"CSAFPID-0001"
]
}
],
"title": "Bundled h2 accepted unbounded empty HTTP/2 DATA frames (RUSTSEC-2026-0258)",
"references": [
{
"category": "external",
"summary": "Threat model entry",
"url": "https://gitlab.com/vPierre/ndaal_public_bsi_grundschutz_oscal_viewer/-/blob/main/documentation/threat-model/stride.md"
}
]
}
]
}