feat(parsers): add native NIST OSCAL 1.2.3 assessment-results parser - #15687
feat(parsers): add native NIST OSCAL 1.2.3 assessment-results parser#15687AAH20 wants to merge 4 commits into
Conversation
Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.57 to 3.1.58. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](gitpython-developers/GitPython@3.1.57...3.1.58) --- updated-dependencies: - dependency-name: gitpython dependency-version: 3.1.58 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cody Maffucci <46459665+Maffooch@users.noreply.github.com>
CI was failing on ruff-linting (blocking Unit Tests Complete and every
downstream test job). Fixed the 13 flagged style violations, 11 via
`ruff --fix`, 2 applied manually after review (ternary conversion, set
literal for membership testing).
While reviewing the two manual fixes, found a real bug beyond lint:
target_status = target.get("status", "") assumed `status` is always a
string, then called target_status.lower(). But the OSCAL 1.2.3 schema
defines finding.target.status as a required OBJECT --
{"state": "satisfied"|"not-satisfied", "reason": "pass"|"fail"|"other"}
-- not a string. Proved this is a real, live interoperability break, not
theoretical: fed this parser the actual output of a just-fixed OSCAL
exporter (prowler-cloud/prowler#12475, which now correctly emits the
object-shaped status per the same schema) and it crashed with
AttributeError: 'dict' object has no attribute 'lower'. Any OSCAL
producer that emits a schema-compliant document would fail to import
here.
Added _is_failed(), which handles both shapes: the correct object shape
(checking state/reason), a bare string (matching this repo's existing
test fixtures, for looser/legacy producers), and target.status being
absent entirely (falls back to the finding-level status prop, matching
the original intent).
Re-ran the exact prowler-output-crashes-this-parser reproduction after
the fix: now parses successfully. Added 3 regression tests (not-
satisfied -> active, satisfied -> mitigated, missing target.status ->
falls back to props) alongside the 4 existing tests (7/7 passing).
ruff clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Fixed the CI failure — Fixed all 13 flagged style violations (11 via While reviewing those two manual fixes, I found a real bug beyond lint: I proved this is a live break, not theoretical: I fed this parser the actual output of a just-fixed OSCAL exporter (prowler-cloud/prowler#12475, which now correctly emits the object-shaped status per the same schema), and it crashed with Added Re-ran the exact prowler-output-crashes-this-parser reproduction after the fix — now parses successfully. Added 3 regression tests alongside the 4 existing ones (7/7 passing). ruff clean. |
The unit tests were injecting a fake dojo.models module (with a
MockFinding accepting any kwargs) before importing the parser, so they
passed in isolation but crashed in the real Django test suite:
dojo.models is already loaded there, so the real Finding model is used,
and Django's FK assignment rejects the MagicMock the tests passed as
`test`. Rewrote the test file to match every other parser test in this
repo (test_prowler_parser.py as reference): django.test.TestCase, a
real (unsaved) Test() instance, and real fixture files read via
get_unit_tests_scans_path("oscal") instead of inline dicts.
Also adds what the original PR was missing entirely, per
unittests/test_parsers.py's own file-existence checks:
- unittests/scans/oscal/*.json -- one fixture per test scenario
(failing finding w/ observation link, passing/mitigated finding,
empty payload, both shapes of target.status, status-missing
fallback to props).
- docs/content/supported_tools/parsers/file/oscal.md, matching the
frontmatter/section structure every other parser doc uses (checked
against prowler.md).
ruff format on dojo/tools/oscal/parser.py (blank line before the class
docstring the formatter doesn't want).
Signed-off-by: aah20 <aah20@users.noreply.github.com>
Summary
Adds a native NIST OSCAL 1.2.3 (Open Security Controls Assessment Language)
assessment-resultsparser underdojo/tools/oscal/.Problem Solved
While DefectDojo supports dozens of legacy vulnerability formats, enterprise and federal compliance teams require ingestion of machine-readable NIST OSCAL 1.2.3
assessment-resultsJSON documents (e.g. produced by Prowler, FedRAMP assessment engines, or custom GRC platforms).This parser:
assessment-resultsJSON documents.AC-3,SC-13,IA-2), and check IDs.Testing & Validation
unittests/tools/test_oscal_parser.pycovering failing findings, passing/mitigated findings, empty payloads, and scan type registration.Upstream & Commercial Context
Maintained by A2Z SOC for enterprise vulnerability management, continuous trust, and FedRAMP / SOC 2 audit readiness.
For organizations requiring automated OSCAL compliance pipelines or GRC readiness sprints: