feat(rate-limiting): Implement core rate limiting functionality with configuration, decision-making, metrics, middleware, and service registration
- Add RateLimitConfig for configuration management with YAML binding support. - Introduce RateLimitDecision to encapsulate the result of rate limit checks. - Implement RateLimitMetrics for OpenTelemetry metrics tracking. - Create RateLimitMiddleware for enforcing rate limits on incoming requests. - Develop RateLimitService to orchestrate instance and environment rate limit checks. - Add RateLimitServiceCollectionExtensions for dependency injection registration.
This commit is contained in:
@@ -311,6 +311,85 @@ Score ≥ 0.70 → HOT (immediate rescan + VEX escalation)
|
||||
Score < 0.40 → COLD (weekly batch)
|
||||
```
|
||||
|
||||
### 17.5 Alternative: Blast Radius + Containment Model
|
||||
|
||||
> **Added**: 2025-12-17 from "Building a Deeper Moat Beyond Reachability" advisory
|
||||
|
||||
An alternative ranking model that incorporates blast radius and runtime containment signals:
|
||||
|
||||
**Unknown reasons tracked**:
|
||||
- missing VEX for a CVE/component
|
||||
- version provenance uncertain
|
||||
- ambiguous indirect call edge for reachability
|
||||
- packed/stripped binary blocking symbolization
|
||||
|
||||
**Rank factors (weighted)**:
|
||||
- **Blast radius**: transitive dependents, runtime privilege, exposure surface (net-facing? in container PID 1?)
|
||||
- **Evidence scarcity**: how many critical facts are missing?
|
||||
- **Exploit pressure**: EPSS percentile (if available), KEV presence
|
||||
- **Containment signals**: sandboxing, seccomp, read-only FS, eBPF/LSM denies observed
|
||||
|
||||
**Data Model**:
|
||||
|
||||
```csharp
|
||||
public sealed record UnknownItem(
|
||||
string Id,
|
||||
string ArtifactDigest,
|
||||
string ArtifactPurl,
|
||||
string[] Reasons,
|
||||
BlastRadius BlastRadius,
|
||||
double EvidenceScarcity,
|
||||
ExploitPressure ExploitPressure,
|
||||
ContainmentSignals Containment,
|
||||
double Score, // 0..1
|
||||
string ProofRef // path inside proof bundle
|
||||
);
|
||||
|
||||
public sealed record BlastRadius(int Dependents, bool NetFacing, string Privilege);
|
||||
public sealed record ExploitPressure(double? Epss, bool Kev);
|
||||
public sealed record ContainmentSignals(string Seccomp, string Fs);
|
||||
```
|
||||
|
||||
**Ranking Function**:
|
||||
|
||||
```csharp
|
||||
public static class UnknownRanker
|
||||
{
|
||||
public static double Rank(BlastRadius b, double scarcity, ExploitPressure ep, ContainmentSignals c)
|
||||
{
|
||||
var dependents01 = Math.Clamp(b.Dependents / 50.0, 0, 1);
|
||||
var net = b.NetFacing ? 0.5 : 0.0;
|
||||
var priv = string.Equals(b.Privilege, "root", StringComparison.OrdinalIgnoreCase) ? 0.5 : 0.0;
|
||||
var blast = Math.Clamp((dependents01 + net + priv) / 2.0, 0, 1);
|
||||
|
||||
var epss01 = ep.Epss is null ? 0.35 : Math.Clamp(ep.Epss.Value, 0, 1);
|
||||
var kev = ep.Kev ? 0.30 : 0.0;
|
||||
var pressure = Math.Clamp(epss01 + kev, 0, 1);
|
||||
|
||||
var containment = 0.0;
|
||||
if (string.Equals(c.Seccomp, "enforced", StringComparison.OrdinalIgnoreCase)) containment -= 0.10;
|
||||
if (string.Equals(c.Fs, "ro", StringComparison.OrdinalIgnoreCase)) containment -= 0.10;
|
||||
|
||||
return Math.Clamp(0.60 * blast + 0.30 * scarcity + 0.30 * pressure + containment, 0, 1);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**JSON Schema**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "unk_...",
|
||||
"artifactPurl": "pkg:...",
|
||||
"reasons": ["missing_vex", "ambiguous_indirect_call"],
|
||||
"blastRadius": { "dependents": 42, "privilege": "root", "netFacing": true },
|
||||
"evidenceScarcity": 0.7,
|
||||
"exploitPressure": { "epss": 0.83, "kev": false },
|
||||
"containment": { "seccomp": "enforced", "fs": "ro" },
|
||||
"score": 0.66,
|
||||
"proofRef": "proofs/unk_.../tree.cbor"
|
||||
}
|
||||
|
||||
## 18. UNKNOWNS DATABASE SCHEMA
|
||||
|
||||
```sql
|
||||
|
||||
Reference in New Issue
Block a user