DIRT Algorithm
DIRT (Dependency Intelligence Risk Tracker) assesses business and security risk based on package metadata, maintainer activity, and historical patterns.
Overview
While RUNT focuses on typosquatting, DIRT evaluates the overall trustworthiness of a package by analyzing multiple risk signals. Even a legitimately-named package can be dangerous if it’s unmaintained, has suspicious metadata, or exhibits risky patterns.
π‘ Why DIRT Matters
70% of supply chain attacks exploit legitimate but vulnerable packages, not typosquats. DIRT catches these by evaluating package health and maintainer reputation.
Risk Signals
DIRT analyzes these signals to calculate a risk score:
| Signal | Weight | Risk Indicator |
|---|---|---|
| π Package Age | 15% | New packages (<30 days) are higher risk |
| π Download Trends | 15% | Sudden spikes or drops indicate anomalies |
| π€ Maintainer Activity | 20% | Inactive maintainers = unpatched vulnerabilities |
| π Dependency Count | 10% | Excessive dependencies increase attack surface |
| π‘οΈ Known CVEs | 25% | Existing vulnerabilities in NVD/OSV databases |
| π License Type | 10% | Missing or unusual licenses are suspicious |
| π README/Docs | 5% | Missing documentation indicates low quality |
Risk Levels
DIRT outputs one of four risk levels:
β LOW (0.0 – 0.3)
Package appears healthy. Well-maintained, no known vulnerabilities, normal activity patterns.
Action: Safe to use
β οΈ MEDIUM (0.3 – 0.6)
Some concerns detected. May have minor issues like infrequent updates or minimal documentation.
Action: Review before using
π΄ HIGH (0.6 – 0.8)
Significant risks identified. Possibly unmaintained, known vulnerabilities, or suspicious patterns.
Action: Avoid or find alternative
π¨ CRITICAL (0.8 – 1.0)
Severe risks. Known malicious package, critical unpatched CVEs, or confirmed compromised maintainer.
Action: Do not use
Asset Criticality Multiplier
DIRT adjusts risk scores based on where the package will be deployed:
| Criticality | Multiplier | Use Case |
|---|---|---|
PUBLIC | 0.5x | Public-facing, non-sensitive (marketing sites, demos) |
INTERNAL | 1.0x | Internal tools, development environments |
CRITICAL | 2.0x | Production systems, customer data, financial |
# Set criticality for scan
falcn scan . --asset-criticality CRITICAL
# In config.yaml
detection:
dirt:
asset_criticality: CRITICAL
β οΈ Production Deployments
Always use CRITICAL for production systems. A MEDIUM risk package becomes HIGH when deployed to critical infrastructure.
Example Output
Healthy Package
π¦ Package: lodash@4.17.21
βββββββββββββββββββββββββββββββββββββββββββββ
DIRT Risk Assessment: LOW (0.12)
Signals:
β
Package Age: 4,380 days (established)
β
Weekly Downloads: 45M (very popular)
β
Last Update: 32 days ago (active)
β
Dependencies: 0 (minimal surface)
β
Known CVEs: 0 (clean)
β
License: MIT (permissive)
Recommendation: Safe to use
Risky Package
π¦ Package: sketchy-utils@0.1.0
βββββββββββββββββββββββββββββββββββββββββββββ
DIRT Risk Assessment: HIGH (0.73)
Signals:
β οΈ Package Age: 12 days (very new)
β οΈ Weekly Downloads: 47 (low adoption)
β Last Update: 12 days ago (single release)
β οΈ Dependencies: 23 (high count)
β Known CVEs: 2 (unpatched)
β License: UNLICENSED (missing)
Risk Factors:
β’ New package with no track record
β’ Excessive dependencies for stated purpose
β’ Known vulnerabilities not addressed
β’ No license specified
Recommendation: Avoid - find established alternative
Configuration
# config.yaml
detection:
dirt:
enabled: true
# Risk thresholds
thresholds:
low: 0.3
medium: 0.6
high: 0.8
# Asset criticality (PUBLIC, INTERNAL, CRITICAL)
asset_criticality: INTERNAL
# Signal weights (must sum to 1.0)
weights:
package_age: 0.15
download_trends: 0.15
maintainer_activity: 0.20
dependency_count: 0.10
known_cves: 0.25
license: 0.10
documentation: 0.05
# CVE severity mapping
cve_weights:
critical: 1.0
high: 0.7
medium: 0.4
low: 0.1
CLI Options
# Run DIRT analysis only
falcn scan . --algorithms dirt
# Set asset criticality
falcn scan . --asset-criticality CRITICAL
# Fail if HIGH or CRITICAL risk found
falcn scan . --fail-on high
# Include CVE details in output
falcn scan . --check-vulnerabilities
# Show all signals (not just flagged)
falcn scan . --verbose
Data Sources
DIRT pulls data from multiple sources:
| Source | Data Provided | Update Frequency |
|---|---|---|
| npm Registry | Package metadata, downloads, maintainers | Real-time |
| PyPI API | Package info, release history | Real-time |
| OSV Database | Open source vulnerabilities | Hourly |
| NVD (NIST) | CVE details and severity | Daily |
| GitHub API | Maintainer activity, repo health | Real-time |
Handling False Positives
Some legitimate packages may trigger DIRT warnings:
- New but legitimate packages β Low download count initially
- Stable packages β May appear “unmaintained” if no updates needed
- Internal packages β Won’t have public download stats
Allowlisting
# config.yaml
detection:
dirt:
allowlist:
- "@mycompany/*" # Internal packages
- "stable-lib" # Known stable package
- "legacy-tool@1.2.3" # Specific version
Combining with RUNT
DIRT and RUNT work together for comprehensive protection:
| Scenario | RUNT | DIRT | Result |
|---|---|---|---|
| Typosquat of popular package | π΄ HIGH | π΄ HIGH (new, low downloads) | CRITICAL |
| Legitimate but vulnerable | β PASS | π΄ HIGH (CVEs) | HIGH |
| Healthy popular package | β PASS | β LOW | SAFE |
| Similar name, healthy package | β οΈ MEDIUM | β LOW | REVIEW |
π‘οΈ Defense in Depth
Running both RUNT and DIRT provides layered protection. RUNT catches naming attacks while DIRT evaluates package health.
Related Documentation
π RUNT Algorithm Typosquatting detection using string similarity. πΈοΈ GTR Algorithm Dependency graph analysis for suspicious patterns. βοΈ Policy Engine Configure BLOCK/ALERT/REVIEW thresholds.