Verify LLM-extracted IOCs against a deterministic parser (close hash/CVE/MITRE trust gap)#14
Open
gadalla11111 wants to merge 1 commit into
Open
Conversation
The LLM tier of the extraction pipeline merged file_hashes_*, cve_identifiers and mitre_techniques verbatim into the result dict; only wallets and URLs were re-verified. A truncated hash, a hallucinated CVE or an invented MITRE technique therefore entered normalisation and could clear the 0.80 confidence floor on method prior alone. Add extractor/verify_gate.py: a belief-gate-style pass that treats the LLM output as the 'required' set and a deterministic parser as the 'present' set. Each format-constrained value must pass two checks (both required): shape (fullmatch against the strict regex from regex_patterns) and grounding (the token actually appears in the source page text). required - present is rejected before merge. Zero runtime deps, never raises (fails open on internal error), toggle via VOIDACCESS_VERIFY_LLM_IOCS. Wire the gate into extract_with_llm just after per-chunk dedup and before the merge loop. Only LLM-added, format-constrained keys are touched; regex/NER values and non-gated LLM keys pass through untouched. Verification: 23 new tests in tests/test_verify_gate.py all pass; test_extractor_llm_pipeline.py and test_llm.py stay green; per-file comparison with and without this change is identical (no regressions in the LLM/extractor/confidence suites).
Author
|
TL;DR — LLM-extracted How to test pytest tests/test_verify_gate.py # 23 tests: shape/grounding/passthrough/flag
VOIDACCESS_VERIFY_LLM_IOCS=false ... # disables the gate (default: on)The gate reuses the strict regexes already in |
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.
Summary
The LLM extraction tier merges
file_hashes_*,cve_identifiersandmitre_techniquesinto the result dict verbatim — only wallets (_classify_wallet) and URLs (.onionsplit) are re-verified. A truncated hash, a hallucinatedCVE-2024-99999, or an inventedT9999therefore reaches normalisation and can clear the 0.80 confidence floor on method prior alone.Fix
New
extractor/verify_gate.pyapplies a set-difference check: the LLM output is the required set, a deterministic parser is the present set, andrequired − presentis rejected before merge. Each format-constrained value must pass both:fullmatchagainst the strict regex already inregex_patterns(single source of truth, so the gate and the regex tier can never drift)Wired into
extract_with_llmright after per-chunk dedup, before the merge loop. Only LLM-added, format-constrained keys are touched; regex/NER values and non-gated LLM keys pass through untouched.Safety
Additive, zero runtime dependencies, never raises (fails open on internal error), and toggleable via
VOIDACCESS_VERIFY_LLM_IOCS=false.Testing
tests/test_verify_gate.pycovering shape rejection, grounding rejection, true positives, mixed batches, passthrough, and the feature flag — all pass.test_extractor_llm_pipeline.pyandtest_llm.pystay green.