Refactor code structure for improved readability and maintainability; optimize performance in key functions.
This commit is contained in:
@@ -1,295 +1,142 @@
|
||||
# CVE → Symbol Mapping
|
||||
# CVE-to-Symbol Mapping
|
||||
|
||||
_Last updated: 2025-12-22. Owner: Scanner Guild + Concelier Guild._
|
||||
|
||||
This document describes how Stella Ops maps CVE identifiers to specific binary symbols/functions for precise reachability analysis.
|
||||
This document describes how StellaOps maps CVE identifiers to specific binary symbols/functions for reachability slices.
|
||||
|
||||
---
|
||||
|
||||
## 1. Overview
|
||||
|
||||
To determine if a vulnerability is reachable, we need to know which specific functions are affected. The **CVE→Symbol Mapping** service bridges:
|
||||
To determine if a vulnerability is reachable, StellaOps resolves:
|
||||
|
||||
- **CVE identifiers** (e.g., `CVE-2024-1234`)
|
||||
- **Package coordinates** (e.g., `pkg:npm/lodash@4.17.21`)
|
||||
- **Affected symbols** (e.g., `lodash.template`, `openssl:EVP_PKEY_decrypt`)
|
||||
|
||||
The mapping is used by `SliceExtractor` to target the right symbols and by downstream VEX decisions.
|
||||
|
||||
---
|
||||
|
||||
## 2. Data Sources
|
||||
|
||||
### 2.1 Patch Diff Analysis
|
||||
### 2.1 Patch Diff Surfaces (Preferred)
|
||||
|
||||
The highest-fidelity source: analyze git commits that fix vulnerabilities.
|
||||
Highest-fidelity source: compute method-level diffs between vulnerable and fixed versions.
|
||||
|
||||
```
|
||||
CVE-2024-1234 fixed in commit abc123
|
||||
→ Diff shows changes to:
|
||||
- src/crypto.c: EVP_PKEY_decrypt() [modified]
|
||||
- src/crypto.c: decrypt_internal() [added guard]
|
||||
→ Affected symbols: EVP_PKEY_decrypt, decrypt_internal
|
||||
```
|
||||
**Implementation**: `StellaOps.Scanner.VulnSurfaces`
|
||||
|
||||
**Implementation**: `StellaOps.Scanner.VulnSurfaces.PatchDiffAnalyzer`
|
||||
### 2.2 Advisory Linksets (Concelier)
|
||||
|
||||
### 2.2 Advisory Metadata
|
||||
Scanner queries Concelier's LNM linksets for package coordinates and optional symbol hints.
|
||||
|
||||
Structured advisories with function-level detail:
|
||||
**Implementation**: `StellaOps.Scanner.Advisory` -> Concelier `/v1/lnm/linksets/{cveId}` or `/v1/lnm/linksets/search`
|
||||
|
||||
- **OSV** (`affected[].ranges[].events[].introduced/fixed`)
|
||||
- **NVD CPE** with CWE → typical affected patterns
|
||||
- **Vendor advisories** (GitHub, npm, PyPI security advisories)
|
||||
### 2.3 Offline Bundles
|
||||
|
||||
**Implementation**: `StellaOps.Concelier.Connectors.*`
|
||||
For air-gapped environments, precomputed bundles map CVEs to packages and symbols.
|
||||
|
||||
### 2.3 Heuristic Inference
|
||||
|
||||
When precise mappings unavailable:
|
||||
|
||||
1. **All public exports** of affected package version
|
||||
2. **CWE-based patterns** (e.g., CWE-79 XSS → output functions)
|
||||
3. **Function name patterns** (e.g., `*_decrypt*`, `*_parse*`)
|
||||
|
||||
**Implementation**: `StellaOps.Scanner.VulnSurfaces.HeuristicMapper`
|
||||
**Implementation**: `FileAdvisoryBundleStore`
|
||||
|
||||
---
|
||||
|
||||
## 3. Mapping Confidence Tiers
|
||||
## 3. Service Contracts
|
||||
|
||||
| Tier | Source | Confidence | Example |
|
||||
|------|--------|------------|---------|
|
||||
| **Confirmed** | Patch diff analysis | 0.95–1.0 | Exact function from git diff |
|
||||
| **Likely** | Advisory with function names | 0.7–0.9 | OSV with `affected.functions[]` |
|
||||
| **Inferred** | CWE/pattern heuristics | 0.4–0.6 | All exports of vulnerable version |
|
||||
| **Unknown** | No data available | 0.0–0.3 | Package-level only |
|
||||
### 3.1 CVE -> Package/Symbol Mapping
|
||||
|
||||
---
|
||||
```csharp
|
||||
public interface IAdvisoryClient
|
||||
{
|
||||
Task<AdvisorySymbolMapping?> GetCveSymbolsAsync(string cveId, CancellationToken ct = default);
|
||||
}
|
||||
|
||||
## 4. Query Interface
|
||||
public sealed record AdvisorySymbolMapping
|
||||
{
|
||||
public required string CveId { get; init; }
|
||||
public ImmutableArray<AdvisoryPackageSymbols> Packages { get; init; }
|
||||
public required string Source { get; init; } // "concelier" | "bundle"
|
||||
}
|
||||
|
||||
### 4.1 Service Contract
|
||||
public sealed record AdvisoryPackageSymbols
|
||||
{
|
||||
public required string Purl { get; init; }
|
||||
public ImmutableArray<string> Symbols { get; init; }
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 CVE + PURL -> Affected Symbols
|
||||
|
||||
```csharp
|
||||
public interface IVulnSurfaceService
|
||||
{
|
||||
/// <summary>
|
||||
/// Get symbols affected by a CVE for a specific package.
|
||||
/// </summary>
|
||||
Task<VulnSurfaceResult> GetAffectedSymbolsAsync(
|
||||
string cveId,
|
||||
string purl,
|
||||
VulnSurfaceOptions? options = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// Batch query for multiple CVE+PURL pairs.
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<VulnSurfaceResult>> GetAffectedSymbolsBatchAsync(
|
||||
IEnumerable<(string CveId, string Purl)> queries,
|
||||
CancellationToken ct = default);
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 Result Model
|
||||
|
||||
```csharp
|
||||
public sealed record VulnSurfaceResult
|
||||
{
|
||||
public required string CveId { get; init; }
|
||||
public required string Purl { get; init; }
|
||||
public required ImmutableArray<AffectedSymbol> Symbols { get; init; }
|
||||
public required VulnSurfaceSource Source { get; init; }
|
||||
public required string Source { get; init; } // "surface" | "package-symbols" | "heuristic"
|
||||
public required double Confidence { get; init; }
|
||||
public DateTimeOffset? CachedAt { get; init; }
|
||||
}
|
||||
|
||||
public sealed record AffectedSymbol
|
||||
{
|
||||
public required string Name { get; init; }
|
||||
public required string SymbolId { get; init; }
|
||||
public string? File { get; init; }
|
||||
public int? Line { get; init; }
|
||||
public string? Signature { get; init; }
|
||||
public SymbolChangeType ChangeType { get; init; }
|
||||
}
|
||||
|
||||
public enum VulnSurfaceSource
|
||||
{
|
||||
PatchDiff,
|
||||
Advisory,
|
||||
Heuristic,
|
||||
Unknown
|
||||
}
|
||||
|
||||
public enum SymbolChangeType
|
||||
{
|
||||
Modified, // Function code changed
|
||||
Added, // New guard/check added
|
||||
Removed, // Vulnerable code removed
|
||||
Renamed // Function renamed
|
||||
public string? MethodKey { get; init; }
|
||||
public string? DisplayName { get; init; }
|
||||
public string? ChangeType { get; init; }
|
||||
public double Confidence { get; init; }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Integration with Concelier
|
||||
## 4. Caching Strategy
|
||||
|
||||
The CVE→Symbol mapping service integrates with Concelier's advisory feed:
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────┐ ┌───────────────────┐
|
||||
│ Scanner │────►│ VulnSurface │────►│ Concelier │
|
||||
│ (Query) │ │ Service │ │ Advisory API │
|
||||
└─────────────────┘ └──────────────────┘ └───────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ Patch Diff │
|
||||
│ Analyzer │
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
### 5.1 Advisory Client
|
||||
|
||||
```csharp
|
||||
public interface IAdvisoryClient
|
||||
{
|
||||
Task<Advisory?> GetAdvisoryAsync(string cveId, CancellationToken ct);
|
||||
Task<IReadOnlyList<AffectedPackage>> GetAffectedPackagesAsync(
|
||||
string cveId,
|
||||
CancellationToken ct);
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 Caching Strategy
|
||||
|
||||
| Data | TTL | Invalidation |
|
||||
|------|-----|--------------|
|
||||
| Advisory metadata | 1 hour | On feed update |
|
||||
| Patch diff results | 24 hours | On new CVE revision |
|
||||
| Heuristic mappings | 15 minutes | On query |
|
||||
| Data | TTL | Notes |
|
||||
|------|-----|------|
|
||||
| Advisory linksets | 1 hour | In-memory cache; configurable TTL |
|
||||
| Offline bundles | Process lifetime | Loaded once from file |
|
||||
|
||||
---
|
||||
|
||||
## 6. Offline Support
|
||||
|
||||
For air-gapped environments:
|
||||
|
||||
### 6.1 Pre-computed Bundles
|
||||
|
||||
```
|
||||
offline-bundles/
|
||||
vuln-surfaces/
|
||||
cve-2024-*.json # Pre-computed mappings
|
||||
ecosystem-npm.json # NPM ecosystem mappings
|
||||
ecosystem-pypi.json # PyPI ecosystem mappings
|
||||
```
|
||||
|
||||
### 6.2 Bundle Format
|
||||
## 5. Offline Bundle Format
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"generatedAt": "2025-12-22T00:00:00Z",
|
||||
"mappings": {
|
||||
"CVE-2024-1234": {
|
||||
"pkg:npm/lodash@4.17.21": {
|
||||
"symbols": ["template", "templateSettings"],
|
||||
"source": "patch_diff",
|
||||
"confidence": 0.95
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Fallback Behavior
|
||||
|
||||
When no mapping is available:
|
||||
|
||||
1. **Ecosystem-specific defaults**:
|
||||
- npm: All `exports` from package.json
|
||||
- PyPI: All public functions (`__all__`)
|
||||
- Native: All exported symbols (`.dynsym`)
|
||||
|
||||
2. **Conservative approach**:
|
||||
- Mark all public APIs as potentially affected
|
||||
- Set confidence = 0.3 (Inferred tier)
|
||||
- Include explanation in verdict reasons
|
||||
|
||||
3. **Manual override**:
|
||||
- Allow user-provided symbol lists via policy
|
||||
- Support suppression rules for known false positives
|
||||
|
||||
---
|
||||
|
||||
## 8. Performance Considerations
|
||||
|
||||
| Metric | Target | Notes |
|
||||
|--------|--------|-------|
|
||||
| Cache hit rate | >90% | Most queries hit cache |
|
||||
| Cold query latency | <500ms | Concelier API call |
|
||||
| Batch throughput | >100 queries/sec | Parallel execution |
|
||||
|
||||
---
|
||||
|
||||
## 9. Example Queries
|
||||
|
||||
### Simple Query
|
||||
|
||||
```http
|
||||
POST /api/vuln-surfaces/query
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"cveId": "CVE-2024-1234",
|
||||
"purl": "pkg:npm/lodash@4.17.21"
|
||||
}
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"cveId": "CVE-2024-1234",
|
||||
"purl": "pkg:npm/lodash@4.17.21",
|
||||
"symbols": [
|
||||
"items": [
|
||||
{
|
||||
"name": "template",
|
||||
"symbolId": "js:lodash/template",
|
||||
"file": "lodash.js",
|
||||
"line": 14850,
|
||||
"changeType": "modified"
|
||||
"cveId": "CVE-2024-1234",
|
||||
"source": "bundle",
|
||||
"packages": [
|
||||
{
|
||||
"purl": "pkg:npm/lodash@4.17.21",
|
||||
"symbols": ["template", "templateSettings"]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": "patch_diff",
|
||||
"confidence": 0.95
|
||||
}
|
||||
```
|
||||
|
||||
### Batch Query
|
||||
|
||||
```http
|
||||
POST /api/vuln-surfaces/batch
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"queries": [
|
||||
{"cveId": "CVE-2024-1234", "purl": "pkg:npm/lodash@4.17.21"},
|
||||
{"cveId": "CVE-2024-5678", "purl": "pkg:pypi/requests@2.28.0"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Related Documentation
|
||||
## 6. Fallback Behavior
|
||||
|
||||
When no surface or advisory mapping is available, the service returns an empty symbol list with low confidence and `Source = "heuristic"`. Callers may inject an `IPackageSymbolProvider` to supply public-symbol fallbacks.
|
||||
|
||||
---
|
||||
|
||||
## 7. Related Documentation
|
||||
|
||||
- [Slice Schema](./slice-schema.md)
|
||||
- [Patch Oracles](./patch-oracles.md)
|
||||
- [Concelier Architecture](../modules/concelier/architecture.md)
|
||||
- [Vulnerability Surfaces](../modules/scanner/vuln-surfaces.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user