fix(analyzer): filter license boilerplate from EA3 static findings (#312) - #328
fix(analyzer): filter license boilerplate from EA3 static findings (#312)#328rodboev wants to merge 2 commits into
Conversation
…VIDIA#312) Signed-off-by: Rod Boev <rod.boev@gmail.com>
rng1995
left a comment
There was a problem hiding this comment.
[Automated SkillSpector Review]
Requesting changes. This suppresses every EA3 finding in any text-like file whose basename resembles LICENSE, COPYING, or NOTICE, without verifying that the matched text is license boilerplate. Skill files remain untrusted regardless of their name, so malicious excessive-agency instructions can be moved into LICENSE.md and bypass EA3 entirely. Please scope suppression to recognized boilerplate content (or otherwise validate legal-file content) and add an adversarial regression showing that non-license instructions in a license-named file remain detectable.
| for module in pattern_modules: | ||
| raw = module.analyze(content=content, file_path=path, file_type=file_type) | ||
| for af in raw: | ||
| if af.rule_id == "EA3" and _is_license_basename(path, file_type): |
There was a problem hiding this comment.
Blocking security issue: this drops every EA3 match based only on the attacker-controlled filename. A skill can place an excessive-agency instruction in LICENSE.md and evade the rule. Please require recognized license-boilerplate content (or another strong legal-file validation) before suppression, and add a regression that preserves EA3 for malicious/non-license content under a license-like basename.
There was a problem hiding this comment.
Thanks for the review. The filename-only gate was too broad, and you're right that a legal-looking name is attacker-controlled. Suppressing on name alone meant a file named LICENSE.md could carry an instruction that EA3 would otherwise report. I've scoped suppression to content.
static_runner.pynow only drops an EA3 finding when all three hold: the file is text-like with a legal basename (the existing_is_license_basename), the file is recognized as a standard license family, and the specific matched line is a canonical license phrase. The new_is_license_boilerplate_linehandles the last two at the gate in_scan_path.- Recognized families are Apache-2.0, MIT, and BSD, detected by distinctive whole-file markers. The canonical-line check covers the EA3 phrase as it appears in each family's standard text:
including but not limited toandnot limited to compiled object codein Apache, and the sharedbut not limited tophrase in MIT and BSD full texts. The issue-312 false positive stays fixed. - Any EA3 match whose line is not a canonical license phrase is still reported. A
LICENSE.mdthat holds only an instruction, or an instruction line slipped into an otherwise genuine Apache file, still produces an EA3 finding. - The earlier tests that used the issue phrase as fake license content now use a recognizable Apache-2.0 block. The guard the review asked for is
test_license_named_file_with_non_boilerplate_content_reports_ea3, with the embedded-instruction and ledger variants sitting next to it.
The net guarantee is specific: an EA3 match is suppressed only when its line is a recognized license-boilerplate phrase in a license-named file. Instructions under a license-like name are reported. One caveat stays on the table: a line that itself embeds a canonical license phrase (for example an instruction sentence containing "including but not limited to") is still suppressed; that is the boundary of the recognized-boilerplate check.
NVIDIA#312) Only suppress an EA3 finding on a text-like legal basename when the matched line is recognized license boilerplate content, so instructions smuggled into license-named files stay reported. Signed-off-by: Rod Boev <rodboev@users.noreply.github.com>
Summary
Static-only scans currently report EA3 Scope Creep findings from Apache-2.0 boilerplate in LICENSE, COPYING, and NOTICE files. This change keeps those files in the scan inventory while filtering the EA3 false positive only where the matched line is recognized license boilerplate in a text-like legal-basename file.
Closes #312
Root cause
The static runner applies EA3 to every cached text-like component. Apache-2.0 contains the phrase not limited to, which matches EA3 even though license text is not skill instruction content. The default LLM path can discard these matches later, but --no-llm reports them directly and sends avoidable findings through the analysis pipeline.
A filename-only suppression cannot be the whole fix: skill filenames are attacker-controlled, so a file named LICENSE.md could hide an excessive-agency instruction from EA3. Suppression therefore also requires the matched line to be recognized license boilerplate, which closes that bypass.
Diff Notes
The suppression behavior follows the reproduction documented in issue 312, including the clarification that the false positive is exposed by --no-llm scans.
Scope
The filter applies only to EA3 matches whose line is recognized license boilerplate inside a text-like legal basename file. License-named files with non-boilerplate content are still reported. Other findings, non-license files, inventory, and report behavior remain unchanged.
Verification