Add HTML security rules with markup search semantics - #75
Open
juangaitanv wants to merge 1 commit into
Open
Conversation
Ports 12 HTML security rule IDs into rules/html/html_security.ron and introduces a SearchSemantics abstraction (src/language.rs) so HTML and Django scanning can use markup-aware prefiltering and final matching instead of taint-rule search, avoiding false negatives when a language has zero taint rules. Wires the new semantics through the scanner's prefilter, match, and dedup paths (scanning_logic.rs, conditions.rs, rules.rs) and adds strictness/unit coverage plus positive and safe HTML fixtures proving the rules fire in default mode without regressing existing suites.
Open
juangaitanv
requested review from
Ibrahimrahhal,
asadeddin,
leenk7991 and
yhoztak
August 25, 2026 19:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #74. This branch sits on
fix-html-taint-regression(af1443e) and must merge after it. A diff againstmainwill also show #74's taint fix; the 12 files below are this PR's own.What this adds
12 HTML security rule IDs in a new
rules/html/html_security.ron, plus a minimal AST-vs-Markup boundary so HTML and Django match search-mode rules against node text rather than resolved function names.src/language.rs— newSearchSemantics { Ast, Markup };LanguageSupport::search_semantics()defaults toAst; HTML and Django override toMarkup.src/scanner/scanning_logic.rs— markup prefiltering and final matching against node text, line attribution to the first positive match, and tightest-span dedup for nested markup findings.src/scanner/conditions.rs—node_kindcondition arm.src/rules.rs—first_positive_match_rangefor line attribution.tests/strictness/html_security.rs(new), registered intests/strictness/main.rs.tests/strictness/helpers.rs/language_coverage.rs—run_cli_raw,run_cli_json,sighthound_binarypromoted from private-in-language_coveragetopubinhelpersso the new suite can drive the CLI. Pure relocation; no coverage lost.Why it depends on #74
Before #74,
src/scanner/modes.rshard-errored when a language had zero taint-mode rules. HTML has none, so every HTML scan exited 1 with zero findings.Verified rather than assumed: revert
modes.rsto its pre-#74 state andhtml_security_rules_fire_in_default_modefails withError: No taint flow rules found. With #74 in the base it passes. This PR adds no hunk tomodes.rs.Review notes
tests/strictness/helpers.rsandtests/strictness/language_coverage.rs. If fix: skip taint pass instead of erroring when a language has no taint rules #74 is amended or force-pushed, the helper move here needs re-deriving.include_dir!staleness: rules are embedded at compile time viainclude_dir!insrc/rules.rs, and there is nobuild.rs. Editing a.ronwith a warmtarget/yields zero findings until youtouch src/rules.rs. Flagging it so the next person loses less time than I did.call_node_types()omitsself_closing_tag, so rules do not fire on self-closing elements. Not introduced here, not fixed here."element"incall_node_types()never produces findings —get_function_nameresolvestag_nameviaCommonUtils::find_child, which walks direct children only, and per tree-sitter-html's node-types anelementhas no directtag_name.Not covered by tests
Markup. The override exists; no test exercises it..expect()in the markup line-attribution block. Unreachable by construction (markup == trueimpliesnode_text.is_some()), but unasserted.get_finding_type()→"vulnerability"fallback.Relationship to #9
#9 carries the same 12 rule IDs from the same lineage; this PR supersedes that portion. #9's sql/xml/properties/config rules, its parser-free text-scanning engine, and its
unlessexclusion mechanism are not included here — all were on this chunk's exclusion list. #9 stays open for that work.Verification
cargo test --test strictness_tests— 47 passedmake test-unit— 261 passedcargo fmt --all -- --check— cleansighthound --output-format json <path>): positive fixture → exit 0, 12 findings at lines 7, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, empty stderr; safe fixture →[]--taint-analysis --output-format json→ stdout is[], notice routed to stderr viaui::warn