Skip to content

Commit 97adfd1

Browse files
authored
Merge pull request #64 from stacknil/stacknil/lgl-04-false-positive-taxonomy
docs(rules): add false-positive taxonomy
2 parents 6028d68 + 3b81182 commit 97adfd1

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

docs/case-study-linux-auth-bruteforce.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ These warnings are useful because they prevent silent overconfidence. A reviewer
119119

120120
## False-positive boundary
121121

122-
The findings should be read as triage statements:
122+
The findings should be read as triage statements and checked against the rule-by-rule taxonomy in [`rule-catalog.md`](./rule-catalog.md):
123123

124124
- `203.0.113.10` is a documentation-range placeholder; in a real case, the same pattern could be an external scanner, shared gateway, internal test, or replayed lab traffic.
125125
- Username spread supports a probing interpretation, but intent is not observable from these lines alone.

docs/rule-catalog.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ JSON findings include both the finding conclusion and the rule context used to r
3939

4040
For `multi_user_probing`, `observed_count` is the distinct username count, while `event_count` remains the number of attempt-evidence events in the selected window.
4141

42+
## False-Positive Taxonomy
43+
44+
The taxonomy names benign or ambiguous explanations a reviewer should consider before interpreting a finding. It is not an allow-list, suppression policy, or automatic disposition.
45+
46+
Each rule uses the same review buckets:
47+
48+
- NAT
49+
- internal scanner
50+
- lab replay
51+
- shared bastion
52+
- scheduled admin task
53+
- malformed log replay
54+
4255
## Brute Force
4356

4457
### Rule name
@@ -85,6 +98,17 @@ This rule identifies concentrated failed SSH authentication evidence from one so
8598

8699
The finding is a triage signal. It is not a compromise verdict, attribution claim, or recommendation to block an address.
87100

101+
### False-positive taxonomy
102+
103+
| Bucket | Review interpretation |
104+
| --- | --- |
105+
| NAT | Multiple legitimate clients behind one egress address can collapse into one `source_ip`. |
106+
| internal scanner | Authorized credential auditing or exposure scanning can intentionally generate repeated failures. |
107+
| lab replay | Sanitized sample data, training fixtures, or repeated demos can preserve concentrated failure patterns. |
108+
| shared bastion | A managed jump host or administrative relay can make many failed attempts appear to come from one source. |
109+
| scheduled admin task | A recurring job with stale credentials can fail repeatedly inside the rule window. |
110+
| malformed log replay | Duplicated or replayed log material can inflate apparent volume; unsupported malformed lines remain warnings and are not counted. |
111+
88112
### Why unsupported evidence is not counted
89113

90114
Unsupported lines are parser warnings, not `AuthSignal` records. They may appear in `top_unknown_patterns`, but they do not carry the `counts_as_terminal_auth_failure` flag required by this rule.
@@ -142,6 +166,17 @@ This rule identifies username spread from one source IP. Username spread can be
142166

143167
The rule does not infer intent. It only states that one source IP produced attempt evidence against multiple usernames inside the configured window.
144168

169+
### False-positive taxonomy
170+
171+
| Bucket | Review interpretation |
172+
| --- | --- |
173+
| NAT | Different users behind one egress address can look like one source probing multiple accounts. |
174+
| internal scanner | Authorized username-enumeration tests or account-audit tooling can touch many usernames by design. |
175+
| lab replay | Replayed lab logs can preserve synthetic username spread without representing live probing. |
176+
| shared bastion | Shared administrative entry points can produce attempts for several accounts from one source IP. |
177+
| scheduled admin task | Account validation, migration, or monitoring jobs can try multiple service or user accounts in one window. |
178+
| malformed log replay | Replayed or partially malformed evidence can duplicate username variety; unsupported records remain parser warnings and do not add usernames. |
179+
145180
### Why unsupported evidence is not counted
146181

147182
Unsupported records do not provide normalized usernames, source IPs, or attempt-evidence flags. Counting them would turn parser uncertainty into detector confidence.
@@ -194,6 +229,17 @@ This rule identifies concentrated sudo command activity by one user. It does not
194229

195230
The finding is strongest when reviewed with session context, change windows, host ownership, and the command text preserved in the report.
196231

232+
### False-positive taxonomy
233+
234+
| Bucket | Review interpretation |
235+
| --- | --- |
236+
| NAT | Usually not a primary explanation because this rule groups by `username`, but it may matter when reviewed alongside source-IP findings. |
237+
| internal scanner | Endpoint assessment, compliance checks, or privileged inventory tooling can run several sudo commands quickly. |
238+
| lab replay | Demo or training logs can replay a compact privileged-command sequence. |
239+
| shared bastion | Shared administrative accounts or jump-host workflows can concentrate privileged commands under one username. |
240+
| scheduled admin task | Maintenance windows, package updates, service repair, or scripted operations can produce bursty sudo activity. |
241+
| malformed log replay | Duplicated sudo lines or replayed command logs can inflate the command count; unsupported malformed sudo-like lines stay out of rule input. |
242+
197243
### Why unsupported evidence is not counted
198244

199245
Unsupported sudo-like lines are parser warnings, not sudo burst signals. They do not carry `counts_as_sudo_burst_evidence`.

0 commit comments

Comments
 (0)