Add comprehensive security tests for OWASP A02, A05, A07, and A08 categories
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Lighthouse CI / Lighthouse Audit (push) Has been cancelled
Lighthouse CI / Axe Accessibility Audit (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Lighthouse CI / Lighthouse Audit (push) Has been cancelled
Lighthouse CI / Axe Accessibility Audit (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
- Implemented tests for Cryptographic Failures (A02) to ensure proper handling of sensitive data, secure algorithms, and key management. - Added tests for Security Misconfiguration (A05) to validate production configurations, security headers, CORS settings, and feature management. - Developed tests for Authentication Failures (A07) to enforce strong password policies, rate limiting, session management, and MFA support. - Created tests for Software and Data Integrity Failures (A08) to verify artifact signatures, SBOM integrity, attestation chains, and feed updates.
This commit is contained in:
291
docs/policy/score-policy-yaml.md
Normal file
291
docs/policy/score-policy-yaml.md
Normal file
@@ -0,0 +1,291 @@
|
||||
# Score Policy YAML Format
|
||||
|
||||
**Sprint:** SPRINT_3402_0001_0001
|
||||
**Status:** Complete
|
||||
|
||||
## Overview
|
||||
|
||||
StellaOps uses a YAML-based configuration for deterministic vulnerability scoring. The score policy defines how different factors contribute to the final vulnerability score, ensuring reproducible and auditable results.
|
||||
|
||||
## Schema Version
|
||||
|
||||
Current version: `score.v1`
|
||||
|
||||
## File Location
|
||||
|
||||
By default, score policies are loaded from:
|
||||
- `etc/score-policy.yaml` (production)
|
||||
- `etc/score-policy.yaml.sample` (reference template)
|
||||
|
||||
Override via environment variable: `STELLAOPS_SCORE_POLICY_PATH`
|
||||
|
||||
## Basic Structure
|
||||
|
||||
```yaml
|
||||
# Required fields
|
||||
policyVersion: score.v1
|
||||
policyId: unique-policy-identifier
|
||||
|
||||
# Optional metadata
|
||||
policyName: "My Organization's Scoring Policy"
|
||||
description: "Custom scoring weights for our security posture"
|
||||
|
||||
# Weight distribution (must sum to 10000 basis points = 100%)
|
||||
weightsBps:
|
||||
baseSeverity: 2500 # 25% - CVSS base score contribution
|
||||
reachability: 2500 # 25% - Code reachability analysis
|
||||
evidence: 2500 # 25% - KEV, EPSS, exploit evidence
|
||||
provenance: 2500 # 25% - Supply chain trust signals
|
||||
```
|
||||
|
||||
## Weight Configuration
|
||||
|
||||
Weights are specified in **basis points (bps)** where 10000 bps = 100%. This avoids floating-point precision issues and ensures weights always sum to exactly 100%.
|
||||
|
||||
### Example: Reachability-Heavy Profile
|
||||
|
||||
```yaml
|
||||
policyVersion: score.v1
|
||||
policyId: reachability-focused
|
||||
|
||||
weightsBps:
|
||||
baseSeverity: 2000 # 20%
|
||||
reachability: 4000 # 40% - Heavy emphasis on reachability
|
||||
evidence: 2000 # 20%
|
||||
provenance: 2000 # 20%
|
||||
```
|
||||
|
||||
### Example: Evidence-Heavy Profile
|
||||
|
||||
```yaml
|
||||
policyVersion: score.v1
|
||||
policyId: evidence-focused
|
||||
|
||||
weightsBps:
|
||||
baseSeverity: 2000 # 20%
|
||||
reachability: 2000 # 20%
|
||||
evidence: 4000 # 40% - Heavy emphasis on KEV/EPSS
|
||||
provenance: 2000 # 20%
|
||||
```
|
||||
|
||||
## Reachability Configuration
|
||||
|
||||
Fine-tune how reachability analysis affects scores:
|
||||
|
||||
```yaml
|
||||
reachabilityConfig:
|
||||
reachableMultiplier: 1.5 # Boost for reachable code paths
|
||||
unreachableMultiplier: 0.3 # Reduction for unreachable code
|
||||
unknownMultiplier: 1.0 # Default when analysis unavailable
|
||||
```
|
||||
|
||||
### Multiplier Bounds
|
||||
|
||||
- Minimum: 0.0
|
||||
- Maximum: 2.0 (configurable)
|
||||
- Default for unknown: 1.0 (no adjustment)
|
||||
|
||||
## Evidence Configuration
|
||||
|
||||
Configure how exploit evidence affects scoring:
|
||||
|
||||
```yaml
|
||||
evidenceConfig:
|
||||
kevWeight: 1.5 # Boost for KEV-listed vulnerabilities
|
||||
epssThreshold: 0.5 # EPSS score threshold for high-risk
|
||||
epssWeight: 1.2 # Weight multiplier for high EPSS
|
||||
```
|
||||
|
||||
### KEV Integration
|
||||
|
||||
Known Exploited Vulnerabilities (KEV) from CISA are automatically boosted:
|
||||
- `kevWeight: 1.5` means 50% score increase for KEV-listed CVEs
|
||||
- Setting `kevWeight: 1.0` disables KEV boost
|
||||
|
||||
### EPSS Integration
|
||||
|
||||
Exploit Prediction Scoring System (EPSS) provides probability-based risk:
|
||||
- `epssThreshold`: Minimum EPSS for applying the weight
|
||||
- `epssWeight`: Multiplier applied when EPSS exceeds threshold
|
||||
|
||||
## Provenance Configuration
|
||||
|
||||
Configure how supply chain trust signals affect scoring:
|
||||
|
||||
```yaml
|
||||
provenanceConfig:
|
||||
signedBonus: 0.1 # 10% reduction for signed artifacts
|
||||
rekorVerifiedBonus: 0.2 # 20% reduction for Rekor-verified
|
||||
unsignedPenalty: -0.1 # 10% increase for unsigned artifacts
|
||||
```
|
||||
|
||||
### Trust Signals
|
||||
|
||||
| Signal | Effect | Use Case |
|
||||
|--------|--------|----------|
|
||||
| `signedBonus` | Score reduction | Artifact has valid signature |
|
||||
| `rekorVerifiedBonus` | Score reduction | Signature in transparency log |
|
||||
| `unsignedPenalty` | Score increase | No signature present |
|
||||
|
||||
## Score Overrides
|
||||
|
||||
Override scoring for specific CVEs or patterns:
|
||||
|
||||
```yaml
|
||||
overrides:
|
||||
# Exact CVE match
|
||||
- id: log4shell-critical
|
||||
match:
|
||||
cvePattern: "CVE-2021-44228"
|
||||
action:
|
||||
setScore: 10.0
|
||||
reason: "Known critical RCE in production"
|
||||
|
||||
# Pattern match
|
||||
- id: log4j-family
|
||||
match:
|
||||
cvePattern: "CVE-2021-442.*"
|
||||
action:
|
||||
multiplyScore: 1.2
|
||||
reason: "Log4j family vulnerabilities"
|
||||
|
||||
# Severity-based
|
||||
- id: low-severity-suppress
|
||||
match:
|
||||
severityEquals: "LOW"
|
||||
action:
|
||||
multiplyScore: 0.5
|
||||
reason: "Reduce noise from low-severity findings"
|
||||
|
||||
# Combined conditions
|
||||
- id: unreachable-medium
|
||||
match:
|
||||
severityEquals: "MEDIUM"
|
||||
reachabilityEquals: "UNREACHABLE"
|
||||
action:
|
||||
multiplyScore: 0.3
|
||||
reason: "Medium + unreachable = low priority"
|
||||
```
|
||||
|
||||
### Override Actions
|
||||
|
||||
| Action | Description | Example |
|
||||
|--------|-------------|---------|
|
||||
| `setScore` | Force specific score | `setScore: 10.0` |
|
||||
| `multiplyScore` | Apply multiplier | `multiplyScore: 0.5` |
|
||||
| `addScore` | Add/subtract value | `addScore: -2.0` |
|
||||
|
||||
### Match Conditions
|
||||
|
||||
| Condition | Description | Example |
|
||||
|-----------|-------------|---------|
|
||||
| `cvePattern` | Regex match on CVE ID | `"CVE-2021-.*"` |
|
||||
| `severityEquals` | Exact severity match | `"HIGH"`, `"CRITICAL"` |
|
||||
| `reachabilityEquals` | Reachability state | `"REACHABLE"`, `"UNREACHABLE"`, `"UNKNOWN"` |
|
||||
| `packagePattern` | Package name regex | `"log4j.*"` |
|
||||
|
||||
## Complete Example
|
||||
|
||||
```yaml
|
||||
policyVersion: score.v1
|
||||
policyId: production-v2024.12
|
||||
policyName: "Production Security Policy"
|
||||
description: |
|
||||
Balanced scoring policy with emphasis on exploitability
|
||||
and reachability for production workloads.
|
||||
|
||||
weightsBps:
|
||||
baseSeverity: 2000
|
||||
reachability: 3000
|
||||
evidence: 3000
|
||||
provenance: 2000
|
||||
|
||||
reachabilityConfig:
|
||||
reachableMultiplier: 1.5
|
||||
unreachableMultiplier: 0.4
|
||||
unknownMultiplier: 1.0
|
||||
|
||||
evidenceConfig:
|
||||
kevWeight: 1.5
|
||||
epssThreshold: 0.3
|
||||
epssWeight: 1.3
|
||||
|
||||
provenanceConfig:
|
||||
signedBonus: 0.1
|
||||
rekorVerifiedBonus: 0.15
|
||||
unsignedPenalty: -0.05
|
||||
|
||||
overrides:
|
||||
- id: critical-rce
|
||||
match:
|
||||
cvePattern: "CVE-2021-44228|CVE-2022-22965"
|
||||
action:
|
||||
setScore: 10.0
|
||||
reason: "Known critical RCE vulnerabilities"
|
||||
|
||||
- id: unreachable-low
|
||||
match:
|
||||
severityEquals: "LOW"
|
||||
reachabilityEquals: "UNREACHABLE"
|
||||
action:
|
||||
multiplyScore: 0.2
|
||||
reason: "Minimal risk: low severity + unreachable"
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
Policies are validated against JSON Schema on load:
|
||||
|
||||
1. **Schema validation**: Structure and types
|
||||
2. **Weight sum check**: `weightsBps` must sum to 10000
|
||||
3. **Range checks**: Multipliers within bounds
|
||||
4. **Override validation**: Valid patterns and actions
|
||||
|
||||
### Programmatic Validation
|
||||
|
||||
```csharp
|
||||
var validator = new ScorePolicyValidator();
|
||||
var result = validator.Validate(policy);
|
||||
if (!result.IsValid)
|
||||
{
|
||||
foreach (var error in result.Errors)
|
||||
{
|
||||
Console.WriteLine(error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Determinism
|
||||
|
||||
For reproducible scoring:
|
||||
|
||||
1. **Policy Digest**: Each policy has a content-addressed digest
|
||||
2. **Replay Manifest**: Digest is recorded in scan manifests
|
||||
3. **Audit Trail**: Policy version tracked with every scan
|
||||
|
||||
### Digest Format
|
||||
|
||||
```
|
||||
sha256:abc123def456...
|
||||
```
|
||||
|
||||
The digest is computed from canonical JSON serialization of the policy, ensuring identical policies always produce identical digests.
|
||||
|
||||
## Migration
|
||||
|
||||
### From Hardcoded Weights
|
||||
|
||||
1. Export current weights to YAML format
|
||||
2. Validate with `stellaops policy validate score.yaml`
|
||||
3. Deploy to `etc/score-policy.yaml`
|
||||
4. Restart services to load new policy
|
||||
|
||||
### Version Upgrades
|
||||
|
||||
Future schema versions (e.g., `score.v2`) will include migration guides and backward compatibility notes.
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Architecture Overview](../07_HIGH_LEVEL_ARCHITECTURE.md)
|
||||
- [Determinism Technical Reference](../product-advisories/14-Dec-2025%20-%20Determinism%20and%20Reproducibility%20Technical%20Reference.md)
|
||||
- [Policy Engine Architecture](../modules/policy/architecture.md)
|
||||
192
docs/policy/scoring-profiles.md
Normal file
192
docs/policy/scoring-profiles.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Scoring Profiles
|
||||
|
||||
**Sprint:** SPRINT_3407_0001_0001
|
||||
**Task:** PROF-3407-014
|
||||
**Last Updated:** 2025-12-16
|
||||
|
||||
## Overview
|
||||
|
||||
StellaOps supports multiple scoring profiles to accommodate different customer needs, from simple transparent scoring to advanced entropy-based analysis. Scoring profiles determine how vulnerability findings are evaluated and scored.
|
||||
|
||||
## Available Profiles
|
||||
|
||||
### Simple Profile
|
||||
|
||||
The Simple profile uses a transparent 4-factor basis-points weighted formula:
|
||||
|
||||
```
|
||||
riskScore = (wB × B + wR × R + wE × E + wP × P) / 10000
|
||||
```
|
||||
|
||||
Where:
|
||||
- **B** (Base Severity): CVSS score × 10 (0-100 range)
|
||||
- **R** (Reachability): Hop-based score with gate multipliers
|
||||
- **E** (Evidence): Evidence points × freshness multiplier
|
||||
- **P** (Provenance): Level-based score (unsigned to reproducible)
|
||||
- **wB, wR, wE, wP**: Weight basis points (must sum to 10000)
|
||||
|
||||
**Default weights:**
|
||||
| Factor | Weight (bps) | Percentage |
|
||||
|--------|-------------|------------|
|
||||
| Base Severity | 1000 | 10% |
|
||||
| Reachability | 4500 | 45% |
|
||||
| Evidence | 3000 | 30% |
|
||||
| Provenance | 1500 | 15% |
|
||||
|
||||
**Use cases:**
|
||||
- Organizations requiring audit-friendly, explainable scoring
|
||||
- Compliance scenarios requiring transparent formulas
|
||||
- Initial deployments before advanced analysis is available
|
||||
|
||||
### Advanced Profile (Default)
|
||||
|
||||
The Advanced profile extends Simple with:
|
||||
|
||||
- **CVSS version adjustment**: Scores weighted by CVSS version (4.0 > 3.1 > 3.0 > 2.0)
|
||||
- **KEV boost**: +20 points for Known Exploited Vulnerabilities
|
||||
- **Uncertainty penalty**: Deductions for missing data (reachability, evidence, provenance, CVSS version)
|
||||
- **Semantic category multipliers**: Entry points and API endpoints scored higher than internal services
|
||||
- **Multi-evidence overlap bonus**: 10% bonus per additional evidence type
|
||||
- **Advanced score passthrough**: Uses pre-computed advanced scores when available
|
||||
|
||||
**Use cases:**
|
||||
- Production deployments with full telemetry
|
||||
- Organizations with mature security programs
|
||||
- Scenarios requiring nuanced risk differentiation
|
||||
|
||||
### Custom Profile (Enterprise)
|
||||
|
||||
The Custom profile allows fully user-defined scoring via Rego policies. Requires:
|
||||
- Valid Rego policy path
|
||||
- Policy Engine license with Custom Scoring feature
|
||||
|
||||
## Configuration
|
||||
|
||||
### Score Policy YAML
|
||||
|
||||
Add the `scoringProfile` field to your score policy:
|
||||
|
||||
```yaml
|
||||
policyVersion: score.v1
|
||||
scoringProfile: simple # Options: simple, advanced, custom
|
||||
|
||||
weightsBps:
|
||||
baseSeverity: 1000
|
||||
reachability: 4500
|
||||
evidence: 3000
|
||||
provenance: 1500
|
||||
|
||||
# ... rest of policy configuration
|
||||
```
|
||||
|
||||
### Tenant Override
|
||||
|
||||
Tenants can override the default profile via the Scoring Profile Service:
|
||||
|
||||
```csharp
|
||||
// Set profile for a tenant
|
||||
scoringProfileService.SetProfileForTenant("tenant-id", new ScoringProfileConfig
|
||||
{
|
||||
Profile = ScoringProfile.Simple
|
||||
});
|
||||
|
||||
// Remove override (revert to default)
|
||||
scoringProfileService.RemoveProfileForTenant("tenant-id");
|
||||
```
|
||||
|
||||
## API Integration
|
||||
|
||||
### Scoring with Default Profile
|
||||
|
||||
```csharp
|
||||
var result = await profileAwareScoringService.ScoreAsync(input);
|
||||
// Uses tenant's configured profile
|
||||
```
|
||||
|
||||
### Scoring with Explicit Profile
|
||||
|
||||
```csharp
|
||||
var result = await profileAwareScoringService.ScoreWithProfileAsync(
|
||||
input,
|
||||
ScoringProfile.Simple);
|
||||
```
|
||||
|
||||
### Profile Comparison
|
||||
|
||||
```csharp
|
||||
var comparison = await profileAwareScoringService.CompareProfilesAsync(input);
|
||||
// Returns scores from all profiles for analysis
|
||||
```
|
||||
|
||||
## Audit Trail
|
||||
|
||||
All scoring results include profile identification:
|
||||
|
||||
```json
|
||||
{
|
||||
"finding_id": "CVE-2024-12345-pkg-1.0.0",
|
||||
"scoring_profile": "simple",
|
||||
"profile_version": "simple-v1",
|
||||
"raw_score": 65,
|
||||
"final_score": 65,
|
||||
"severity": "medium",
|
||||
"signal_values": {
|
||||
"baseSeverity": 75,
|
||||
"reachability": 70,
|
||||
"evidence": 45,
|
||||
"provenance": 60
|
||||
},
|
||||
"signal_contributions": {
|
||||
"baseSeverity": 7.5,
|
||||
"reachability": 31.5,
|
||||
"evidence": 13.5,
|
||||
"provenance": 9.0
|
||||
},
|
||||
"explain": [
|
||||
{ "factor": "baseSeverity", "value": 75, "reason": "CVSS 7.5 (v3.1) with version adjustment" },
|
||||
{ "factor": "evidence", "value": 45, "reason": "45 evidence points, 14 days old (90% freshness)" },
|
||||
{ "factor": "provenance", "value": 60, "reason": "Provenance level: SignedWithSbom" },
|
||||
{ "factor": "reachability", "value": 70, "reason": "2 hops from call graph" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Migration Guide
|
||||
|
||||
### From Legacy Scoring
|
||||
|
||||
1. **Audit current scores**: Export current scores for baseline comparison
|
||||
2. **Enable Simple profile**: Start with Simple for predictable behavior
|
||||
3. **Compare profiles**: Use `CompareProfilesAsync` to understand differences
|
||||
4. **Gradual rollout**: Move to Advanced when confidence is established
|
||||
|
||||
### Profile Switching Best Practices
|
||||
|
||||
- **Test in staging first**: Validate score distribution before production
|
||||
- **Monitor severity distribution**: Watch for unexpected shifts
|
||||
- **Document changes**: Record profile changes in policy lifecycle
|
||||
- **Use replay**: Re-score historical findings to validate behavior
|
||||
|
||||
## Determinism
|
||||
|
||||
Both Simple and Advanced profiles are fully deterministic:
|
||||
|
||||
- **Explicit time**: All calculations use `AsOf` timestamp
|
||||
- **Integer math**: Basis-point arithmetic avoids floating-point drift
|
||||
- **Stable ordering**: Explanations sorted alphabetically by factor
|
||||
- **Input digests**: Track input hashes for replay validation
|
||||
|
||||
## Performance
|
||||
|
||||
| Profile | Typical Latency | Memory |
|
||||
|---------|----------------|--------|
|
||||
| Simple | < 1ms | Minimal |
|
||||
| Advanced | < 5ms | Minimal |
|
||||
| Custom | Varies | Depends on Rego complexity |
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Score Policy YAML](./score-policy-yaml.md)
|
||||
- [Signals Weighting](./signals-weighting.md)
|
||||
- [VEX Trust Model](./vex-trust-model.md)
|
||||
- [Policy Overview](./overview.md)
|
||||
Reference in New Issue
Block a user