benchmark: add OWASP starter corpus and fix EXAMPLE.json glob bug - #25
benchmark: add OWASP starter corpus and fix EXAMPLE.json glob bug#25visit2rahul wants to merge 3 commits into
Conversation
|
Thanks for this — the corpus research is genuinely good work. I verified the findings independently and they hold up: all three pinned commits exist, and the line references are accurate (juice-shop Two blocking issues before this can merge, though. 1. The validator rejects this PR's own corpusThe test-plan boxes are unchecked, and
To be clear on which side is wrong: the per-file numbering is right. Real reports start at 001 and sequence monotonically, and the corpus should keep that. The uniqueness check should be scoped per file. 2. Scoping the validator per-file exposes a silent scoring bug (pre-existing)This is the more serious one. That keying is not new — it's identical on the base commit and unchanged by this PR. It's dormant on With the validator relaxed to per-file scoping, the corpus loads — and then: All four WebGoat and NodeGoat findings are silently overwritten by juice-shop's, and the detection rate is computed over 2 instead of 6. A loud (Verified by driving the real corpus through Fix is internal namespacing, not renaming findings. Judgments already carry Sites: the five judgment read/write points in Smaller items
Test coverageNo tests are added, and the existing suite can't catch any of this: every case in All of this is checkable offline — validation runs before any network I/O and @emeth- — you know this area far better than I do, particularly the judgment/history keying and whether the composite-key change should ride along here or land as its own PR ahead of it. Could you take a look? The ordering matters: if the corpus merges before the keying fix, the benchmark silently reports 2 of 6. |
|
Thanks @schenksj - agree with most everything you said, just adding one piece of intent that isn't visible from the code.
On # 2, your analysis is why I'd avoid the per-file relaxation. The flat keying is only safe while IDs are unique, and the validator is what enforces that - so I'd keep the guardrail, renumber the six findings, and #2 can't fire. No keying change needed for correctness, and it unblocks the PR. The full composite key proposal is reasonable defense-in-depth, but I'd land it as its own PR rather than a prerequisite; the ordering risk you flagged goes away once the corpus is globally numbered. Couple of smaller things: the README should probably state the scope outright ("globally unique across the whole corpus"). And the |
… PathTraversal, IDOR Adds six verified vulnerability findings across three OWASP intentionally vulnerable apps (Juice Shop, WebGoat, NodeGoat) with precise file/line references and pinned commit hashes so the benchmark stays reproducible.
…tion EXAMPLE.json was picked up by load_all_benchmarks() glob and failed at clone phase on every fresh run due to placeholder commit hashes. Rename to EXAMPLE.json.template so it is excluded from *.json glob. Add _validate_benchmarks() to catch missing required fields, duplicate finding IDs, and malformed source_code URLs before any network I/O, replacing cryptic KeyError/IndexError crashes with clear error messages. Closes capitalone#24.
Prefix all finding IDs with app name (NODEGOAT-/WEBGOAT-/JUICE-) so IDs are globally unique across corpus files, as required by the flat judgment keying in run.py and finding_history.py. Add isinstance(finding, dict) guard in _validate_benchmarks so a JSON array of strings raises a clean error instead of AttributeError on finding.keys(). Clarify README to state finding_id is globally unique across the entire corpus, not just within one file. Add prefixing convention example. Add tests/test_corpus_integrity.py: loads the real shipped corpus and validates it, checks global ID uniqueness, and unit-tests all four validator rejection paths. Runs in ~0.05s with no network and no model.
d67426f to
7201a9c
Compare
|
Thank you @schenksj and @emeth-. Went with @emeth-'s direction -- prefixed all six IDs (NODEGOAT-001/002, WEBGOAT-001/002, JUICE-001/002) and left the validator global. Cleaner than touching the keying code, and the duplicate check now enforces it. Also added the Please review as your time permits. |
Fixes #24, closes #23.
Summary
EXAMPLE.jsonwas included in the*.jsonglob used byload_all_benchmarks(). Its placeholder commit hashes do not exist on GitHub, sopython -m local_harness.benchmark.runalways failed at the clone phase on a fresh checkout. Renamed toEXAMPLE.json.templateso it is excluded from the glob._validate_benchmarks()inrun.pyto catch missing required fields, duplicatefinding_idvalues, and malformedsource_codeURLs before any network I/O -- replacing crypticKeyError/IndexErrorcrashes with clear upfront errors.Corpus added
juice-shop.jsonWebGoat.jsonNodeGoat.jsonTest plan
python -m local_harness.benchmark.run --scan-onlyon a fresh checkout no longer fails at clone phasesource_codeURL prints a clear error and exits before cloningEXAMPLE.json.templateis not loaded by the benchmark runner