Skip to content

fix(advisory): validate vex overlay at load time - #10

Open
MarkAtwood wants to merge 1 commit into
fix/cdx-vex-per-productfrom
fix/overlay-validation
Open

fix(advisory): validate vex overlay at load time#10
MarkAtwood wants to merge 1 commit into
fix/cdx-vex-per-productfrom
fix/overlay-validation

Conversation

@MarkAtwood

Copy link
Copy Markdown

load_overlay only json.load'd the overlay, so a hand-edited entry the schema forbids passed through — most dangerously a not_affected determination with no justification, which silently degraded the VEX output. Adds a stdlib validator enforcing the schema's structural invariants (required state; not_affectedjustification for entry + fips; enums; CVE-id keys; no unknown keys), with a drift test tying the vocabulary to the schema file. Adds TestOverlayValidation.

⚠️ Top of the advisory stack. Merge order: #7 → path-traversal → CDX per-product → this.

load_overlay only json.load'd the overlay, so a hand-edited entry the
schema forbids passed straight through -- above all a not_affected
determination with no justification, which then degraded to a default
CSAF flag and an omitted CycloneDX analysis.justification (the two VEX
outputs silently disagreeing).

Add a stdlib validator enforcing the overlay schema's structural
invariants at load (required state, not_affected => justification for
both the entry and its fips sub-object, enum membership, CVE-id keys,
no unknown keys). The authoritative jsonschema pass still runs in CI;
a drift test ties the validator's vocabulary to the schema file.

77 advisory tests pass (69 + 8 new).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds load-time validation for the advisory VEX overlay to prevent schema-forbidden overlays (notably not_affected without a justification) from silently degrading emitted CSAF/CycloneDX VEX output, and introduces tests to prevent validator/schema vocabulary drift.

Changes:

  • Add a stdlib-only overlay validator in load_overlay() enforcing key schema invariants (CVE-keyed map, enum vocab, required state, not_affectedjustification, no unknown keys).
  • Add TestOverlayValidation unit tests, including a schema-vocabulary drift guard against advisory-vex-overlay.schema.json.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
central/gen-advisory Adds overlay vocabulary constants and load-time validation for overlays, rejecting schema-invalid inputs early.
central/test_gen_advisory.py Adds TestOverlayValidation to verify rejection/acceptance rules and guard validator/schema drift.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread central/gen-advisory
Comment on lines +846 to +869
state = obj.get(state_key)
if state_required and state is None:
sys.exit(f"ERROR: overlay {cve} {kind} is missing required "
f"{state_key!r}")
if state is not None and state not in _STATE_TO_BUCKET:
sys.exit(f"ERROR: overlay {cve} {kind} {state_key}={state!r} is not a "
f"valid state ({', '.join(sorted(_STATE_TO_BUCKET))})")
just = obj.get('justification')
if state == 'not_affected' and not just:
sys.exit(f"ERROR: overlay {cve} {kind} has {state_key}=not_affected "
f"but no 'justification' (required so a CSAF flag / CycloneDX "
f"analysis.justification can be emitted)")
if just is not None and just not in _JUSTIFICATION_TO_CSAF_FLAG:
sys.exit(f"ERROR: overlay {cve} {kind} justification={just!r} is not "
f"valid ({', '.join(sorted(_JUSTIFICATION_TO_CSAF_FLAG))})")
resp = obj.get('response')
if resp is not None and (not isinstance(resp, list)
or any(r not in _OVERLAY_RESPONSES for r in resp)):
sys.exit(f"ERROR: overlay {cve} {kind} response must be a list drawn "
f"from {', '.join(sorted(_OVERLAY_RESPONSES))}")
ds = obj.get('default_status')
if ds is not None and ds not in _OVERLAY_DEFAULT_STATUS:
sys.exit(f"ERROR: overlay {cve} {kind} default_status={ds!r} is not "
f"valid ({', '.join(sorted(_OVERLAY_DEFAULT_STATUS))})")
Comment thread central/gen-advisory
Comment on lines +823 to +826
# Overlay vocabulary, mirroring advisory-vex-overlay.schema.json. The state and
# justification enums are the maps' own keys; the two below and the allowed-key
# sets complete the schema. test_overlay_vocab_matches_schema guards drift.
_OVERLAY_RESPONSES = {'can_not_fix', 'will_not_fix', 'update', 'rollback',
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants