ndaal Informational Advisory: strict CSAF 2.1 stance pinned for non-UTF-8 advisories + per-distribution resilience added to the CSAF importer. (1) 77 of 85,559 (0.09%) openSUSE/SUSE CSAF advisories ship non-UTF-8 bytes inside JSON string fields, violating RFC 8259 §8.1 and CSAF 2.1 §9.1.5; `crates/vl-feeders/src/csaf_generic.rs` now skips these advisories cleanly with an RFC-cited `tracing::warn!` and a pinning unit test (`test_read_to_string_rejects_non_utf8`) freezes the strict-decode contract. (2) TuxCare's provider-metadata.json advertises 144 distributions of which 4 (on repo.tuxcare.com — centos7-els + oraclelinux7-els × advisories+vex) return HTTP 404 on both index.txt and changes.csv; `crates/vl-feeders/src/csaf_downloader.rs` no longer propagates the first per-distribution discovery failure with `?` — it logs a warning, increments `report.failed`, and continues with sibling distributions, so the 140 working TuxCare distributions on security.tuxcare.com now import successfully instead of being aborted by the first 404. Byte distribution across the 77 non-UTF-8 files: 30× 0xae (®), 26× 0xe9 (é), 20× 0xa0 (NBSP), 16× 0xf6 (ö), 10× 0xb3 (³), 10× 0xb9 (¹), 9× 0xa7 (§), 4× 0xea (ê), 3× 0xfc (ü), 3× 0xb0 (°), 2× 0xe1 (á), 1× 0xb6 (¶), 1× 0xf8 (ø), 1× 0xb2 (²), 1× 0xed (í). Year distribution: 2019:1, 2020:7, 2021:3, 2022:6, 2023:12, 2024:5, 2025:17, 2026:23. Not a security vulnerability under CVSS — no CIA impact; severity informational. Sidecar checksums (.sha-256/.sha-512/.sha3-512/.blake3-512/.shake256-512) regenerated.

Edit JSON

Metadata

Tracking IDndaal-sa-2026-044
Categorycsaf_informational_advisory
CSAF Version2.1
Statusfinal
Version1.0.0
Publisherndaal Gesellschaft fuer Sicherheit in der Informationstechnik mbH & Co KG
TLPCLEAR
Initial Release2026-05-15T13:30:00.000Z
Current Release2026-05-15T13:30:00.000Z

Vulnerabilities (0)

No vulnerabilities.

Raw JSON

{
  "$schema": "https://docs.oasis-open.org/csaf/csaf/v2.1/schema/csaf.json",
  "document": {
    "category": "csaf_informational_advisory",
    "csaf_version": "2.1",
    "distribution": {
      "tlp": {
        "label": "CLEAR"
      }
    },
    "lang": "en",
    "notes": [
      {
        "category": "summary",
        "text": "Two related findings + fixes shipped together.\n\nFINDING 1 — openSUSE / SUSE CSAF feed: 77 / 85,559 (0.09%) of advisories from a single upstream publisher (openSUSE / SUSE) contain Latin-1 / CP1252 bytes inside JSON string fields, violating RFC 8259 §8.1 (\"JSON text exchanged between systems that are not part of a closed ecosystem MUST be encoded using UTF-8\") and CSAF 2.1 §9.1.5 (\"A CSAF document MUST be encoded in UTF-8\").  Bytes seen: 0xae=®, 0xe9=é, 0xa0=NBSP, 0xf6=ö, 0xb3=³, 0xb9=¹, 0xa7=§, 0xea=ê, 0xfc=ü, 0xb0=°, 0xe1=á, 0xb6=¶, 0xf8=ø, 0xb2=², 0xed=í.\n\nFIX 1 (strict mode + clean skip) — `crates/vl-feeders/src/csaf_generic.rs` was changed to keep its existing strict `tokio::fs::read_to_string` decode (UTF-8 only) and skip non-compliant files cleanly with an explicit, RFC-cited warning so operators understand it is an upstream-publisher bug.  This is the *opposite* of a Latin-1 fallback / salvage path: nvulnlookup deliberately stays a strict CSAF 2.1 consumer.  Three motivations: (a) the bytes-on-disk stay a faithful mirror of the upstream feed (no encoding transformation in our import pipeline); (b) the operator sees an `InvalidData` warning that routes the bug to the publisher (`bugzilla.suse.com`) instead of masking it; (c) downstream consumers querying our database get only spec-compliant content.  Cost: 77 advisories per import cycle missing from the index until openSUSE fixes their emitter — accepted because at 0.09% of the csaf_opensuse corpus the data-loss is bounded and visible, and salvaging would set a precedent of papering over spec violations.\n\nFINDING 2 — TuxCare CSAF feed: of 144 distributions advertised by `https://security.tuxcare.com/csaf/v2/provider-metadata.json`, 4 are hosted on the `repo.tuxcare.com` subdomain (centos7-els + oraclelinux7-els × {advisories, vex}) and return HTTP 404 on both `index.txt` and `changes.csv`.  The other 140 (all on `security.tuxcare.com`) work normally.  The downloader propagated the first 404 with `?` and aborted the entire feeder, losing the 140 working distributions too.\n\nFIX 2 (per-distribution resilience) — `crates/vl-feeders/src/csaf_downloader.rs` no longer propagates `discover_advisories` errors with `?` from the per-distribution loop.  Failures now log a warning and increment `report.failed` so sibling distributions still run.  TuxCare's 140 working distributions now import successfully and the 4 broken ones surface as visible per-directory warnings the operator can route to TuxCare support."
      },
      {
        "category": "description",
        "text": "## Survey method\n\nA Python sweep over `data/feeders/csaf/**/*.json` attempted\nUTF-8 decode of every file's bytes; failure was recorded.  Of\n170,526 scanned files exactly 77 failed, all of them under the\n`csaf_opensuse` provider directory.\n\n## openSUSE / SUSE — byte distribution across the 77 affected files\n\n| byte  | count | Latin-1 / CP1252 meaning             |\n|-------|------:|--------------------------------------|\n| 0xae  |    30 | ® (registered trademark)             |\n| 0xe9  |    26 | é (small e with acute accent)        |\n| 0xa0  |    20 | non-breaking space (NBSP)            |\n| 0xf6  |    16 | ö (small o with diaeresis)           |\n| 0xb3  |    10 | ³ (superscript three)                |\n| 0xb9  |    10 | ¹ (superscript one)                  |\n| 0xa7  |     9 | § (section sign)                     |\n| 0xea  |     4 | ê (small e with circumflex)          |\n| 0xfc  |     3 | ü (small u with diaeresis)           |\n| 0xb0  |     3 | ° (degree sign)                      |\n| 0xe1  |     2 | á (small a with acute accent)        |\n| 0xb6  |     1 | ¶ (pilcrow sign)                     |\n| 0xf8  |     1 | ø (small o with stroke)              |\n| 0xb2  |     1 | ² (superscript two)                  |\n| 0xed  |     1 | í (small i with acute accent)        |\n\nEvery byte above is a 1-byte Latin-1 / CP1252 encoding of a\ncharacter that, in proper UTF-8, would require 2 bytes (e.g.\n® = 0xC2 0xAE).  The upstream files emit the 1-byte form\ndirectly inside a JSON string, which is what makes them\nnon-UTF-8.\n\n## openSUSE / SUSE — upstream-advisory year distribution\n\n74 of the 77 filenames parse cleanly against the openSUSE /\nSUSE naming convention.  Year distribution:\n\n  2019:  1\n  2020:  7\n  2021:  3\n  2022:  6\n  2023: 12\n  2024:  5\n  2025: 17\n  2026: 23\n\nThe spread across seven calendar years rules out a one-off\nencoding incident; openSUSE's CSAF publishing pipeline has a\npersistent encoding-correctness gap that has been in production\nsince at least 2019.\n\n## openSUSE / SUSE — three production-log samples\n\nObserved in the live `vl-web` feeder scheduler (worktree\n`vigilant-proskuriakova-981064`, 2026-05-15T14:50:16 –\n15:04:31Z):\n\n  * suse-su-2026_20869-1.json  → byte 0xa7 at offset 3490\n      context: `RFC 7515 §4.1.11`\n  * suse-su-2023_3383-1.json   → byte 0xae at offset 648\n      context: `Intel® Processors`\n  * suse-su-2019_3191-1.json   → byte 0xe9 at offset 2451\n      context: `Gonéri Le Bouder`\n\n## TuxCare — distribution-host split\n\nProbed `https://security.tuxcare.com/csaf/v2/provider-metadata.json`\non 2026-05-15T15:30Z:\n\n  * total distributions advertised:  144\n  * on `security.tuxcare.com`:       140  (index.txt + changes.csv\n                                            return HTTP 200)\n  * on `repo.tuxcare.com`:             4  (index.txt + changes.csv\n                                            return HTTP 404)\n\nThe 4 broken paths are:\n\n  https://repo.tuxcare.com/security/csaf/v2/els_os/centos7-els/advisories/\n  https://repo.tuxcare.com/security/csaf/v2/els_os/centos7-els/vex/\n  https://repo.tuxcare.com/security/csaf/v2/els_os/oraclelinux7-els/advisories/\n  https://repo.tuxcare.com/security/csaf/v2/els_os/oraclelinux7-els/vex/\n\nAll four return an nginx 404 placeholder.  TuxCare must\neither populate `index.txt` + `changes.csv` at these paths\nor remove the four entries from the provider-metadata\ndistributions array.\n\n## Standards basis (Finding 1)\n\n  * RFC 8259 §8.1 — \"JSON text exchanged between systems that\n    are not part of a closed ecosystem MUST be encoded using\n    UTF-8.\"\n  * CSAF 2.1 §9.1.5 — \"A CSAF document MUST be encoded in\n    UTF-8.\"\n\nThe affected openSUSE / SUSE advisories therefore violate\nboth the underlying transfer format and the CSAF profile that\nlayers on top of it.\n\n## Standards basis (Finding 2)\n\n  * CSAF 2.1 §7.1.7 (Provider) — a Trusted Provider's\n    `provider-metadata.json` SHOULD only advertise distribution\n    `directory_url` entries that are reachable.  Advertising\n    a path whose `index.txt` is HTTP 404 produces a poor\n    discovery experience for consumers and (without resilient\n    consumers) causes silent data loss across the rest of the\n    publisher's catalogue.",
        "title": "Technical detail"
      },
      {
        "category": "details",
        "text": "## Operational impact assessment\n\n  * Feeder reliability (openSUSE / SUSE) — UNCHANGED\n    relative to pre-fix behaviour, but now LOUDER.  The 77\n    non-UTF-8 advisories continue to be skipped (same as\n    before) — what changes is the warning text: it now\n    explicitly names RFC 8259 §8.1 / CSAF 2.1 §9.1.5 and\n    instructs the operator that the upstream publisher must\n    fix the encoding.  An InvalidData-typed `io::Error`\n    branch handles the well-known case separately from\n    generic I/O failures so operators can grep for one or\n    the other.\n\n  * Feeder reliability (TuxCare) — IMPROVED MATERIALLY.\n    Before the fix, TuxCare contributed 0 advisories on\n    every import cycle (the first 404 from one of the 4\n    broken repo.tuxcare.com distributions propagated\n    up via `?` and aborted the feeder before any of the\n    140 working security.tuxcare.com distributions ran).\n    After the fix, the 140 working distributions are\n    imported normally and the 4 broken ones surface as\n    per-directory `tracing::warn!` lines that the operator\n    can route to TuxCare support without blocking the\n    rest of the import.\n\n  * Downstream consumer compatibility — UNCHANGED.\n    Strict-UTF-8 enforcement means the bytes-on-disk in\n    nvulnlookup remain a faithful mirror of the upstream\n    feeds; no encoding transformation, no salvage layer,\n    no risk of subtly different text reaching downstream\n    consumers than what the upstream actually published.\n\n  * Sidecar checksums — UNAFFECTED.  Both fixes are\n    consumer-side decode / resilience logic; on-disk\n    advisory files are read unchanged.  Upstream\n    SHA-512 sidecars therefore continue to verify and the\n    importer's SHA-512 sidecar gate (introduced in\n    v0.1.42) still works for all affected files.\n\n  * GDPR / data-protection — NEUTRAL.  No personal data\n    is added, removed, or transformed by either fix.\n    The contributor name `Gonéri Le Bouder` that appears\n    in one of the samples is already public information\n    published by openSUSE.\n\n  * Security classification — NOT a security\n    vulnerability under CVSS.  Finding 1 is a data\n    availability gap (0.09% of csaf_opensuse silently\n    missing from the index) intentionally accepted in\n    favour of strict-mode purity.  Finding 2 is a\n    data-availability gap (TuxCare contributing 0\n    advisories per cycle) that the fix closes by\n    isolating per-distribution failures.  Neither has\n    CIA-triad impact on either side.\n\nThis advisory is filed as `csaf_informational_advisory`\nper CSAF 2.1 §3.1.27.3.  No CVE is requested.",
        "title": "Operational impact"
      },
      {
        "category": "general",
        "text": "## Recommended action for the upstream publisher (openSUSE / SUSE)\n\nFix the CSAF-emitter encoding bug at source.  Every JSON\nstring field MUST be UTF-8 per RFC 8259 §8.1 and CSAF 2.1\n§9.1.5.  In practice the publisher's templating layer is\nlikely concatenating advisory text from heterogenous\ninputs (some UTF-8, some CP1252) without normalising; a\nsingle pass of `iconv -f CP1252 -t UTF-8` on the\noffending fields before JSON-serialisation would fix the\nentire class of bug.  Track this fix at\n<https://bugzilla.suse.com> under the \"SUSE Security\" /\n\"OpenSUSE Security\" components.\n\n## Recommended action for the upstream publisher (TuxCare)\n\nEither populate `index.txt` and `changes.csv` at the four\n`repo.tuxcare.com` distribution paths listed above, OR\nremove those four entries from the `distributions[]`\narray in `provider-metadata.json`.  Either action makes\nthe published metadata consistent with the live directory\nlayout.  Issue reportable at <https://support.tuxcare.com>.\n\n## Recommended action for downstream consumers\n\nNO ACTION REQUIRED if you are running nvulnlookup ≥ 0.1.44\n(both fixes are in this release).  If you are running an\nearlier version: (a) the openSUSE / SUSE encoding\nincident already manifested in your import cycles as\nsilent skips; (b) the TuxCare feeder was contributing 0\nadvisories — upgrading recovers ~140 distributions worth\nof advisories.\n\nConsumers of other openSUSE / SUSE feeds (raw rpmlint\noutput, CVRF mirrors, etc.) should audit their own decode\npath — the same encoding bug surfaces wherever the\nopenSUSE security feed is consumed strictly.  Consumers\nof the TuxCare feed that walk `provider-metadata.json`\nshould check their own loop for the same\nabort-on-first-404 pattern.\n\n## Verification (Finding 1 — strict UTF-8 skip)\n\n  # 1. Confirm strict mode is the contract:\n  grep -n 'CSAF file is not valid UTF-8' \\\n    vulnerability-lookup-rs/crates/vl-feeders/src/csaf_generic.rs\n\n  # 2. Confirm pinning test passes:\n  ( cd vulnerability-lookup-rs && \\\n    cargo test -p vl-feeders csaf_generic::tests::test_read_to_string_rejects_non_utf8 )\n  # Expected: 1 passed.\n\n  # 3. Re-run the local-tree UTF-8 sweep to confirm the\n  # count is still 77 / 170,526:\n  python3 - <<'PY'\nimport os, collections\nroot = 'data/feeders/csaf'\nbad = collections.Counter()\ntotal = 0\nfor dp, _dn, fn in os.walk(root):\n    prov = os.path.relpath(dp, root).split(os.sep)[0]\n    for f in fn:\n        if not f.endswith('.json'):\n            continue\n        total += 1\n        try:\n            open(os.path.join(dp, f), 'rb').read().decode('utf-8')\n        except UnicodeDecodeError:\n            bad[prov] += 1\nprint(f'Scanned: {total}, non-UTF-8: {sum(bad.values())}')\nfor p, n in bad.most_common():\n    print(f'  {p}: {n}')\nPY\n  # Expected:\n  #   Scanned: 170526, non-UTF-8: 77\n  #     csaf_opensuse: 77\n\n## Verification (Finding 2 — TuxCare per-distribution resilience)\n\n  # 1. Confirm the resilient loop is in place:\n  grep -n 'CSAF distribution discovery failed' \\\n    vulnerability-lookup-rs/crates/vl-feeders/src/csaf_downloader.rs\n\n  # 2. Confirm the live broken paths are still 404:\n  for u in \\\n    https://repo.tuxcare.com/security/csaf/v2/els_os/centos7-els/advisories/index.txt \\\n    https://repo.tuxcare.com/security/csaf/v2/els_os/centos7-els/vex/index.txt \\\n    https://repo.tuxcare.com/security/csaf/v2/els_os/oraclelinux7-els/advisories/index.txt \\\n    https://repo.tuxcare.com/security/csaf/v2/els_os/oraclelinux7-els/vex/index.txt ; do\n    printf '%s: ' \"$u\"\n    curl -sS -o /dev/null -w 'HTTP %%{http_code}\\n' \"$u\"\n  done\n  # Expected: HTTP 404 on all four (until TuxCare fixes upstream).\n\n  # 3. Confirm the working host:\n  curl -sS -o /dev/null -w 'HTTP %{http_code}\\n' \\\n    https://security.tuxcare.com/csaf/v2/els_alt_nodejs/debian13/advisories/index.txt\n  # Expected: HTTP 200.\n\n## Complete list of openSUSE / SUSE non-UTF-8 files (77)\n\nAll under data/feeders/csaf/csaf_opensuse/ in the local\nmirror; the same basenames appear under\nhttps://ftp.suse.com/pub/projects/security/csaf/ and\nhttps://ftp.opensuse.org/pub/projects/security/csaf/.\n\ncve-2026-21714.json, opensuse-su-2020_0403-1.json,\nopensuse-su-2020_0937-1.json, opensuse-su-2020_1153-1.json,\nopensuse-su-2020_1236-1.json, opensuse-su-2021_0587-1.json,\nopensuse-su-2021_0595-1.json, opensuse-su-2022_10144-1.json,\nopensuse-su-2022_10145-1.json, opensuse-su-2023_0365-1.json,\nopensuse-su-2023_0366-1.json, opensuse-su-2024_0005-1.json,\nopensuse-su-2024_0342-1.json, opensuse-su-2025_0074-1.json,\nopensuse-su-2025_0145-1.json, opensuse-su-2026_10397-1.json,\nopensuse-su-2026_10504-1.json, opensuse-su-2026_20431-1.json,\nopensuse-su-2026_20476-1.json, opensuse-su-2026_20519-1.json,\nopensuse-su-2026_20620-1.json, opensuse-su-2026_20654-1.json,\nsuse-ru-2024_0029-1.json, suse-ru-2024_4213-1.json,\nsuse-su-2019_3191-1.json, suse-su-2020_0743-1.json,\nsuse-su-2020_2105-1.json, suse-su-2020_2832-1.json,\nsuse-su-2021_0773-1.json, suse-su-2022_1485-1.json,\nsuse-su-2022_2174-1.json, suse-su-2022_2291-1.json,\nsuse-su-2022_2416-1.json, suse-su-2023_3289-1.json,\nsuse-su-2023_3359-1.json, suse-su-2023_3382-1.json,\nsuse-su-2023_3383-1.json, suse-su-2023_4343-1.json,\nsuse-su-2023_4345-1.json, suse-su-2023_4351-1.json,\nsuse-su-2023_4375-1.json, suse-su-2023_4378-1.json,\nsuse-su-2023_4414-1.json, suse-su-2024_0917-1.json,\nsuse-su-2024_1139-1.json, suse-su-2024_4105-1.json,\nsuse-su-2025_01987-1.json, suse-su-2025_01989-1.json,\nsuse-su-2025_01991-1.json, suse-su-2025_03444-1.json,\nsuse-su-2025_21040-1.json, suse-su-2025_21052-1.json,\nsuse-su-2025_21056-1.json, suse-su-2025_21064-1.json,\nsuse-su-2025_4111-1.json, suse-su-2025_4128-1.json,\nsuse-su-2025_4139-1.json, suse-su-2025_4140-1.json,\nsuse-su-2025_4149-1.json, suse-su-2025_4301-1.json,\nsuse-su-2025_4320-1.json, suse-su-2026_1062-1.json,\nsuse-su-2026_1107-1.json, suse-su-2026_1117-1.json,\nsuse-su-2026_1199-1.json, suse-su-2026_1299-1.json,\nsuse-su-2026_1363-1.json, suse-su-2026_1371-1.json,\nsuse-su-2026_1389-1.json, suse-su-2026_1400-1.json,\nsuse-su-2026_1478-1.json, suse-su-2026_1509-1.json,\nsuse-su-2026_20839-1.json, suse-su-2026_20869-1.json,\nsuse-su-2026_20879-1.json, suse-su-2026_20934-1.json,\nsuse-su-2026_21181-1.json\n\n## Rollback\n\nNot recommended.  Reverting Finding 1's strict-mode\nwarning would weaken operator diagnostics on the\nupstream-publisher bug.  Reverting Finding 2's\nper-distribution resilience would re-introduce silent\nloss of ~140 TuxCare distributions per import cycle.\nBoth fixes are small and well-tested (one helper-edit\nplus one pinning test in csaf_generic.rs, one match-arm\nedit in csaf_downloader.rs).",
        "title": "Recommended action"
      },
      {
        "category": "other",
        "text": "Disposition: informational — strict-mode CSAF 2.1 stance pinned + per-distribution resilience added to the importer.  Finding 1: 77 / 85,559 (0.09%) of csaf_opensuse advisories ship Latin-1 / CP1252 bytes inside JSON string fields, violating RFC 8259 §8.1 and CSAF 2.1 §9.1.5; importer now skips them with an RFC-cited warning instead of a generic I/O message.  Finding 2: TuxCare advertises 144 distributions in `provider-metadata.json` but 4 of them (on repo.tuxcare.com) return HTTP 404 on index.txt + changes.csv; importer now isolates per-distribution failures so the 140 working ones still run.  Status final.",
        "title": "Disposition"
      },
      {
        "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."
      }
    ],
    "publisher": {
      "category": "vendor",
      "contact_details": "security@ndaal.eu",
      "issuing_authority": "ndaal Gesellschaft fuer Sicherheit in der Informationstechnik mbH & Co KG Security Team",
      "name": "ndaal Gesellschaft fuer 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/044/ndaal-sa-2026-044.json"
      },
      {
        "category": "external",
        "summary": "RFC 8259 — The JavaScript Object Notation (JSON) Data Interchange Format; §8.1 mandates UTF-8",
        "url": "https://www.rfc-editor.org/rfc/rfc8259#section-8.1"
      },
      {
        "category": "external",
        "summary": "OASIS CSAF 2.1 — §9.1.5 mandates UTF-8 encoding for CSAF documents",
        "url": "https://docs.oasis-open.org/csaf/csaf/v2.1/csaf-v2.1.html"
      },
      {
        "category": "external",
        "summary": "OASIS CSAF 2.1 csaf.json schema",
        "url": "https://docs.oasis-open.org/csaf/csaf/v2.1/schema/csaf.json"
      },
      {
        "category": "external",
        "summary": "openSUSE / SUSE CSAF Trusted Provider feed root (mirror of the 77 affected advisories)",
        "url": "https://ftp.suse.com/pub/projects/security/csaf/"
      },
      {
        "category": "external",
        "summary": "SUSE Bugzilla — appropriate venue for tracking the upstream encoding fix",
        "url": "https://bugzilla.suse.com/"
      },
      {
        "category": "external",
        "summary": "TuxCare CSAF Trusted Provider — provider-metadata.json",
        "url": "https://security.tuxcare.com/csaf/v2/provider-metadata.json"
      },
      {
        "category": "external",
        "summary": "TuxCare CSAF feed root (the 140 working distributions live here)",
        "url": "https://security.tuxcare.com/csaf/v2/"
      },
      {
        "category": "external",
        "summary": "TuxCare support — appropriate venue for the four 404 distribution paths",
        "url": "https://support.tuxcare.com/"
      },
      {
        "category": "external",
        "summary": "ISO/IEC 8859-1 (Latin-1) — code-page used by the affected openSUSE files",
        "url": "https://www.iso.org/standard/28245.html"
      },
      {
        "category": "external",
        "summary": "Companion advisory ndaal-sa-2026-043 (strict CSAF 2.1 validation sweep)",
        "url": "https://gitlab.com/vPierre/ndaal_public_nvulnlookup/-/raw/main/csaf/2026/043/ndaal-sa-2026-043.json"
      }
    ],
    "title": "ndaal Informational Advisory: strict CSAF 2.1 stance pinned for non-UTF-8 advisories + per-distribution resilience added to the CSAF importer.  (1) 77 of 85,559 (0.09%) openSUSE/SUSE CSAF advisories ship non-UTF-8 bytes inside JSON string fields, violating RFC 8259 §8.1 and CSAF 2.1 §9.1.5; `crates/vl-feeders/src/csaf_generic.rs` now skips these advisories cleanly with an RFC-cited `tracing::warn!` and a pinning unit test (`test_read_to_string_rejects_non_utf8`) freezes the strict-decode contract.  (2) TuxCare's provider-metadata.json advertises 144 distributions of which 4 (on repo.tuxcare.com — centos7-els + oraclelinux7-els × advisories+vex) return HTTP 404 on both index.txt and changes.csv; `crates/vl-feeders/src/csaf_downloader.rs` no longer propagates the first per-distribution discovery failure with `?` — it logs a warning, increments `report.failed`, and continues with sibling distributions, so the 140 working TuxCare distributions on security.tuxcare.com now import successfully instead of being aborted by the first 404.  Byte distribution across the 77 non-UTF-8 files: 30× 0xae (®), 26× 0xe9 (é), 20× 0xa0 (NBSP), 16× 0xf6 (ö), 10× 0xb3 (³), 10× 0xb9 (¹), 9× 0xa7 (§), 4× 0xea (ê), 3× 0xfc (ü), 3× 0xb0 (°), 2× 0xe1 (á), 1× 0xb6 (¶), 1× 0xf8 (ø), 1× 0xb2 (²), 1× 0xed (í).  Year distribution: 2019:1, 2020:7, 2021:3, 2022:6, 2023:12, 2024:5, 2025:17, 2026:23.  Not a security vulnerability under CVSS — no CIA impact; severity informational.  Sidecar checksums (.sha-256/.sha-512/.sha3-512/.blake3-512/.shake256-512) regenerated.",
    "tracking": {
      "current_release_date": "2026-05-15T13:30:00.000Z",
      "generator": {
        "engine": {
          "name": "ndaal CSAF Generator",
          "version": "1.0.0"
        }
      },
      "id": "ndaal-sa-2026-044",
      "initial_release_date": "2026-05-15T13:30:00.000Z",
      "revision_history": [
        {
          "date": "2026-05-15T13:30:00.000Z",
          "number": "1.0.0",
          "summary": "Initial informational advisory bundling two findings + fixes: (1) 77 / 85,559 csaf_opensuse advisories ship Latin-1 / CP1252 bytes that violate RFC 8259 §8.1 + CSAF 2.1 §9.1.5; importer pinned to strict UTF-8 with a clearer skip warning + a pinning unit test that freezes the contract; (2) TuxCare provider-metadata.json advertises 144 distributions of which 4 (on repo.tuxcare.com) return HTTP 404 on index.txt and changes.csv; downloader's per-distribution loop now isolates failures so 140 working distributions still run instead of being aborted by the first 404.  Status: final."
        }
      ],
      "status": "final",
      "version": "1.0.0"
    }
  },
  "product_tree": {
    "branches": [
      {
        "category": "vendor",
        "name": "ndaal Gesellschaft fuer Sicherheit in der Informationstechnik mbH & Co KG",
        "branches": [
          {
            "category": "product_name",
            "name": "nvulnlookup CSAF importer (crate vl-feeders)",
            "branches": [
              {
                "category": "product_version_range",
                "name": "vers:cargo/<0.1.44",
                "product": {
                  "name": "vl-feeders CSAF importer prior to 0.1.44 — generic `Failed to read CSAF file` warning on non-UTF-8 (no RFC citation, no skip-rationale); per-distribution `?` propagation aborts TuxCare on the first repo.tuxcare.com 404 (140 working distributions lost per import cycle)",
                  "product_id": "CSAFPID-0001"
                }
              },
              {
                "category": "product_version",
                "name": "0.1.44",
                "product": {
                  "name": "vl-feeders CSAF importer 0.1.44 — strict UTF-8 enforced with RFC-cited skip warning (operator gets a routable diagnostic instead of a generic I/O message); per-distribution loop isolates discovery failures (TuxCare's 140 working security.tuxcare.com distributions import normally; the 4 broken repo.tuxcare.com paths surface as per-directory warnings)",
                  "product_id": "CSAFPID-0002"
                }
              }
            ]
          }
        ]
      }
    ]
  }
}

Are you sure?