Repository navigation
refactor: one source of truth for the detection rules - #6
Merged
Merged
Conversation
The rules lived in polinrider_scan.sh and org_sweep.sh separately, plus a third
hardcoded copy inside classify_config(). They drifted: the sweep matched the
campaign tag as the literal 'A9-3727' long after the scanner had generalised it,
which left the sweep blind to the wave-1 variant on every run it ever performed.
Nobody noticed, because a rule that has drifted still reports CLEAN.
rules.sh is now the only place a rule is written down. Both scripts source it and
abort if it is missing.
It is not a flat list. The two tools have different false-positive surfaces and
that difference was deliberate, so the file carries three sets:
core rmcej%otb%, wuqktam... hard everywhere
repo-only 'Sec-V', helloipbot, hard in a repo sweep
AUTH_API_KEY, 9-3727-2
host-only atob(process.env.AUTH_API_KEY hard on a workstation
Flattening these would have promoted 'Sec-V' to a hard indicator on developer
machines, where it appears as quoted text in Claude Code transcripts -- a
recorded FP class that would produce false COMPROMISED verdicts.
Three things surfaced while doing this:
- Neither tool carried the bare 9-3727-2 literal. Both relied on the marker
pattern alone, which requires the global-assignment context to match. The
handoff lists that literal as load-bearing. It is now in the repo set.
- classify_config() held a third copy of the signatures, inline.
- The comment claiming the payload line carries ~5,000 padding spaces was wrong.
It is 507, measured on all three obfuscated carriers. The conclusion that
comment supported was right; the number was not.
test_rules_single_source.sh, 21 assertions: both sets non-empty, the shared
indicators in both, the deliberate split preserved in each direction, no script
defining a rule inline, both scripts sourcing and aborting without rules.sh, and
the marker matching every known build plus a rotated one it has never seen.
All five suites pass. Verified against the four byte-exact carriers: all four
detected, marker fires on all three obfuscated builds including A9-3727-3.
Known gap, recorded rather than solved: rules.sh is the single source for BASH
consumers. A non-bash consumer -- the PR-check service -- cannot source it. That
needs a canonical format both can read, decided when we know what the service is
written in. Do not solve it by copying the strings.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fabrizzio-dotCMS
force-pushed
the
rules/single-source
branch
from
August 28, 2026 17:44
8436003 to
ad909e3
Compare
Member
Author
|
Auto-closed as merged: its base branch |
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 #3 — review that one first; this diff is only the last commit (
8436003).Why
The detection rules lived in three places:
polinrider_scan.sh,org_sweep.sh, and a thirdhardcoded copy inside
classify_config(). They had drifted. The sweep was still matching thecampaign tag as the literal
A9-3727long after the scanner generalised it, which left thesweep blind to the wave-1 variant on every run it ever performed — and nobody noticed,
because a rule that has drifted still reports CLEAN.
rules.shis now the only place a rule is written down. Both scripts source it and abort ifit is missing.
Not a flat list — three context sets
The two tools have different false-positive surfaces, and that difference was deliberate:
corermcej%otb%,wuqktam…repo-only'Sec-V',helloipbot,AUTH_API_KEY,9-3727-2host-onlyatob(process.env.AUTH_API_KEYFlattening these would promote
'Sec-V'to a hard indicator on developer machines, where itappears as quoted text in Claude Code transcripts — a recorded FP class that would produce
false COMPROMISED verdicts.
Surfaced while doing this
9-3727-2literal. Both relied on the marker pattern alone,which requires the global-assignment context to match. That literal is load-bearing; it is
now in the repo set.
classify_config()held a third, inline copy of the signatures.507, measured on all three obfuscated carriers. The conclusion the comment supported was
right; the number was not. Anchor on the run length, never on a column.
Tests
test_rules_single_source.sh, 21 assertions: both sets non-empty, shared indicators present inboth, the deliberate split preserved in each direction, no script defining a rule inline, both
scripts sourcing
rules.shand aborting without it, and the marker matching every known buildplus a rotated one it has never seen.
All five suites pass. Verified against the four byte-exact carriers: all four detected, marker
fires on all three obfuscated builds including
A9-3727-3.Known gap — recorded, not solved
rules.shis the single source for bash consumers. A non-bash consumer — the PR-checkservice — cannot source it. That needs a canonical format both can read, decided once we know
what the service is written in. Do not close this gap by copying the strings; that
recreates exactly the drift this PR removes.