Count-Based¶
A count crossed a fixed threshold. What separates these from composition is that the count is over indicators of one kind rather than over distinct kinds, and what separates them from corpus behavioral is that the threshold is a configured constant rather than a deviation from a learned baseline.
H036 counts obfuscation indicators on one line. H030 counts added
dependencies weighted by rarity. H045, H052 and H055 count packages in a
cluster. Every threshold is configurable under [thresholds], and every
one was set against the benign corpus rather than chosen.
See the rule system reference for the field table, the severity weights and the reserved identifier ranges.
Rules on this page¶
| Rule | Name | Severity |
|---|---|---|
| H030 | Dependency-Set Expansion | MEDIUM |
| H036 | Shell Obfuscation Density | MEDIUM |
| H045 | Mass Adoption | HIGH |
| H052 | Shared Source Repository | HIGH |
| H055 | Attribute Burst | MEDIUM |
H030: Dependency-Set Expansion¶
- Target: programmatic (delta over dependency arrays × per-dep novelty)
- Severity: MEDIUM (weight 15) - corpus rate 0.34 %
- Category:
dependency - Condition: A single diff adds 3+
depends/makedepends/optdepends/checkdependsentries whose count × mean rarity exceeds the expansion gate (≥1.5, tuned on corpus).
Why not count alone: Adding 5 deps that are all common (glibc, qt6-base, cmake) is a normal heavy build and should not fire. The signal is count weighted by how rare/novel each added dep is, reusing D001's dependency_observation_count as a rarity proxy. Novel/obscure deps push the magnitude up; common deps contribute near zero.
No double-count with D001: H030 fires on the aggregate pattern (multiple rare deps appearing together), which is a materially different signal from any single dep being novel. Individual D001 per-dep firings remain untouched. This is not the H027 mistake: the aggregate condition captures a different phenomenon (co-occurrence, not individual presence).
Origin: Socket/Snyk dependency-surface profiling - a version bump that expands the dependency graph with obscure entries is the "expand attack surface quietly" shape. D001 already flags each novel dep individually; H030 catches the disproportionate co-occurrence.
H036: Shell Obfuscation Density¶
- Target: programmatic (resolved build-function lines, position-scoped)
- Severity: MEDIUM (weight 15)
- Category:
obfuscation - Condition: A single added line inside a critical build function (
build(),prepare(),check(),package()) contains 3 or more distinct obfuscation indicators:
| Indicator | Pattern |
|---|---|
| Base64 decode | base64 -d / base64 --decode |
| Hex escape | printf '\x...' |
| Command substitution | $( or ` |
| Eval | eval |
| Pipe to shell | \| bash / \| sh / \| zsh |
| URL shortener | bit.ly, t.co, tinyurl, shorturl, ow.ly, is.gd |
| Quiet wget pipe | wget -q -O - \| |
| Variable expansion with network/shell | ${var}...curl / ${var}...bash |
A single obfuscation indicator is unusual but can be legitimate (e.g. eval
for dynamic configuration). Three or more on the same line is characteristic
of deliberately hidden behaviour: each layer adds indirection, and the density
itself is the signal.
H045: Mass Adoption¶
- Severity: HIGH (weight 25)
- Category:
adoption - Condition: One maintainer submitted at least
[thresholds] h045.min_packages(default 10) packages withinh045.window_days(default 7).
H052: Shared Source Repository¶
- Severity: HIGH (weight 25)
- Category:
adoption - Condition: At least
[thresholds] h052.min_packages(default 3) otherwise unrelated packages share a source repository, a new domain, or an adoption window.
H055: Attribute Burst¶
- Severity: MEDIUM (weight 15)
- Category:
adoption - Condition: At least
[thresholds] h055.min_packages(default 5) packages sharing a maintainer were modified withinh055.window_hours(default 24).
Only modified packages count. H045 already claims the added-package clusters, so counting additions here would report the same maintainer twice.