fix(api_sonarqube): add descriptionSections support and dynamic mitigation mapping#15157
fix(api_sonarqube): add descriptionSections support and dynamic mitigation mapping#15157uzx-02 wants to merge 3 commits into
Conversation
|
@DryRunSecurity fp drs_d1ce2b2e This is a confirmed false positive. The entire concatenated payload string is explicitly routed through DefectDojo's native sanitize_rule_details() function, which utilizes Mozilla's bleach.clean() library to robustly sanitize the final output against XSS vectors. |
|
Finding d1ce2b2e has been successfully dismissed and marked as False Positive. |
| def test_get_rule_details_handles_description_sections(self): | ||
| # Load the newly created synthetic 2025/2026 rule payload fixture | ||
| with open("unittests/scans/api_sonarqube/rule_description_sections_only.json") as f: | ||
| rule_data = json.load(f) | ||
|
|
||
| importer = SonarQubeApiImporter() | ||
| details = importer.get_rule_details(rule_data) | ||
|
|
||
| # Verify backward-compatible structure and alignment | ||
| self.assertIn("Root Cause", details) | ||
| self.assertIn("Mitigation", details) | ||
|
|
||
| # Verify truncation matches: clean_rule_description_html should halt at <h2>References</h2> | ||
| clean_description = importer.clean_rule_description_html(details) | ||
| self.assertNotIn("References", clean_description) | ||
|
|
||
| # Verify CWE can successfully extract out from the returned details payload string | ||
| cwe_extracted = importer.clean_cwe(details) | ||
| self.assertEqual(cwe_extracted, 95) | ||
|
|
There was a problem hiding this comment.
Can you turn this into asserts on the findings generated by the parser?
|
On deduplication/hashcode impact (since this changes finding fields): no hashcode impact, and no recalculation is required. This importer feeds the The diff only changes
For completeness, the other SonarQube parsers are unaffected: |
valentijnscholten
left a comment
There was a problem hiding this comment.
Can you look at the asserts and rebase against bugfix or dev?
….1.0-3.2.0-dev Release: Merge back 3.1.0 into dev from: master-into-dev/3.1.0-3.2.0-dev
Hey @valentijnscholten, thanks for the look. Fair point on the test case, I'll refactor it to check the final findings from the top-level parser instead of testing the helper method by itself. I'll get that updated, rebase on dev, and clear that Ruff error. Will push it up shortly. |
…ation mapping - Refactored test cases to utilize DefectDojo's native DojoTestCase framework, ensuring full database fixture integration and end-to-end coverage via parser.get_findings(). - Eliminated legacy string-based open() logic in unit tests, migrating file I/O operations to use pathlib.Path.open(encoding="utf-8") to completely clear PLW1514 and PTH123 Ruff linting violations. - Implemented robust assertions against real, generated Finding model attributes (description, mitigation, cwe) to guarantee data structure alignment with downstream parsing contracts. - Resolved out-of-date branch drift by cleanly rebasing the feature branch on top of upstream/dev HEAD.
7fd7542 to
138d92c
Compare
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
Description
Prior to SonarQube v2025.1.1, rules API responses included either an
htmlDesc(raw HTML) ormdDesc(Markdown) field for rule descriptions. Starting with the v2025.1.1 and v2026 release builds, SonarQube omits both legacy fields entirely for specific rule classes and instead returns a structured array calleddescriptionSections, where each element carries akey(e.g.,root_cause,how_to_fix,resources) and an HTMLcontentstring.The previous
get_rule_details()method had no fallback logic for this new schema structure, causing it to silently return an empty string for all modern payloads. This broke description rendering, compliance taxonomy tagging, and reference links parsing across all recent installations (Issue #12565).Changes Introduced
get_rule_details()Three-Path Fallback (importer.py)descriptionSectionsarray, maps them dynamically into an ordered layout (<h3>Root Cause</h3>,<h3>Mitigation</h3>, and<h2>References</h2>), and passes the aggregate through the sanitization pipeline.<h2>References</h2>header signature is explicitly designated to align with the downstreamclean_rule_description_html()truncation regex execution mapping (r'^(.*?)(?:(<h2>See</h2>)|(<h2>References</h2>)|...)'), cleanly separating technical details from trailing link items in the web UI interface view.import_issues()Dynamic Mitigation Pipeline (importer.py)"No mitigation provided"string parameter.how_to_fixdata payload natively into DefectDojo's dedicatedmitigationdatabase container field, optimizing layout transparency. Legacy payloads safely fall back to the default string context.Test Coverage & Validation
unittests/scans/api_sonarqube/rule_description_sections_only.jsonmapping a complete standalone mock payload signature containing strictly modern description arrays.test_get_rule_details_handles_description_sections()to the activeTestSonarqubeImporterRuleDetailsSanitizationsuite class validating string inclusion, structural split isolation boundaries, and cascading extraction handling (CWE-95).OKstatus signature within0.055s.Closes #12565