Repository navigation
CSAF-2.1: Failed Mandatory Test 6.1.26 #738
Description
csaf-validator-lib/csaf_2_1/mandatoryTests/mandatoryTest_6_1_26.js (Test 6.1.26 "Prohibited Document Category Name") produces incorrect results for several official OASIS CSAF TC conformance test vectors shipped in csaf/csaf_2.1/test/validator/data/mandatory/:
| Test file | Expected | Actual |
|---|---|---|
oasis_csaf_tc-csaf_2_1-2024-6-1-26-15.json (csaf_vulnerability_report) |
valid | invalid |
oasis_csaf_tc-csaf_2_1-2024-6-1-26-09.json (Vulnerability_report) |
invalid | valid |
oasis_csaf_tc-csaf_2_1-2024-6-1-26-22.json (dash look-alikes) |
invalid | valid |
oasis_csaf_tc-csaf_2_1-2024-6-1-26-23.json (connector look-alikes) |
invalid | valid |
oasis_csaf_tc-csaf_2_1-2024-6-1-26-24.json (invisible characters) |
invalid | valid |
Root Causes
A) Missing 9th profile
allowedCategoryValues only lists the 8 profiles from earlier drafts and is missing
csaf_vulnerability_report (Profile 9 "Vulnerability Report", CSAF 2.1 spec §4.9).
This causes:
- The legitimate value
csaf_vulnerability_reportto be flagged as using the
reservedcsaf_prefix (false failure,-15). - The similarly-named value
Vulnerability_reportto not be recognized as a
prohibited name collision (false pass,-09).
B) Incomplete Unicode separator coverage
SEPARATOR_PATTERN (/[\p{Dash}\p{Pc}\u0332\s]+/gu) is used to strip
dash/underscore/whitespace-like characters before comparing the category value
against profile names, per spec:
Any occurrences of dash, hyphen, minus, underscore, white space and invisible
characters are removed from the values on both sides before the case insensitive
match.
However, the test vectors -22, -23, -24 use dash-, connector-, and
invisible-character look-alikes that fall outside \p{Dash} / \p{Pc}, e.g.:
- Box-drawing/technical dash symbols (
\p{gc=So}, e.g. U+23AF, U+2500, U+2796) - A math symbol (
\p{gc=Sm}, U+29FF) - A Duployan letter used purely as a visual underscore stand-in (
\p{gc=Lo}, U+1BC86) - Format/invisible characters (
\p{gc=Cf}, e.g. U+200B ZWSP, U+FEFF,
U+2060 WORD JOINER) which aren't covered at all currently
Because these characters aren't stripped, the normalized string doesn't match the
prohibited profile name, so the check silently passes.
Proposed Solutions
Option A — Extend the pattern with explicit codepoints
Add \p{Cf} (covers all invisible-character cases) plus an explicit list of the
remaining dash-/connector-like codepoints not covered by any Unicode property
(derived directly from the official test vectors):
const SEPARATOR_PATTERN =
/[\p{Dash}\p{Pc}\p{Cf}\u02D7\u02CD\u0332\u0333\u034F\u2017\u2043\u2053\u2581\u23AF\u23B5\u23BA\u23BB\u23BC\u23BD\u23E4\u2500\u2501\u254C\u254D\u2574\u2576\u2578\u257A\u2796\u29FF\u{1BC03}\u{1BC08}\u{1BC0D}\u{1BC11}\u{1BC12}\u{1BC13}\u{1BC86}\u{1BC96}\u{1BC97}\u{1BC99}\s]+/guPlus add 'csaf_vulnerability_report' to allowedCategoryValues.
Option B — Use a Unicode confusables (UTS #39) library
Use a "confusables skeleton" implementation (per
Unicode Technical Standard #39: Unicode Security Mechanisms,
e.g. npm packages confusables or unicode-confusables) to normalize look-alike
characters to their canonical form before comparison, instead of (or in addition to)
manual separator stripping.
Activity
DevPhilB commentedon Sep 22, 2026
We chose Option A for the following reasons:
tests-01-mndtr-26-prohibited-document-category-name.md) explicitly listscsaf_vulnerability_reportas one of the profile values the test must skip, confirming the 9th profile was simply missing fromallowedCategoryValues.\p{Cf}for invisible/format characters), rather than relying on an opaque third-party confusables table whose behavior for this specific character set isn't guaranteed.