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:
434
docs/api/evidence-decision-api.openapi.yaml
Normal file
434
docs/api/evidence-decision-api.openapi.yaml
Normal file
@@ -0,0 +1,434 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: StellaOps Evidence & Decision API
|
||||
description: |
|
||||
REST API for evidence retrieval and decision recording.
|
||||
Sprint: SPRINT_3602_0001_0001
|
||||
version: 1.0.0
|
||||
license:
|
||||
name: AGPL-3.0-or-later
|
||||
url: https://www.gnu.org/licenses/agpl-3.0.html
|
||||
|
||||
servers:
|
||||
- url: /v1
|
||||
description: API v1
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
|
||||
paths:
|
||||
/alerts:
|
||||
get:
|
||||
operationId: listAlerts
|
||||
summary: List alerts with filtering and pagination
|
||||
tags:
|
||||
- Alerts
|
||||
parameters:
|
||||
- name: band
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum: [critical, high, medium, low, info]
|
||||
- name: severity
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
- name: status
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum: [open, acknowledged, resolved, suppressed]
|
||||
- name: artifactId
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
- name: vulnId
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
- name: componentPurl
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
- name: limit
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 50
|
||||
maximum: 500
|
||||
- name: offset
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
responses:
|
||||
'200':
|
||||
description: Alert list
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AlertListResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/alerts/{alertId}:
|
||||
get:
|
||||
operationId: getAlert
|
||||
summary: Get alert details
|
||||
tags:
|
||||
- Alerts
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/alertId'
|
||||
responses:
|
||||
'200':
|
||||
description: Alert details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AlertSummary'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/alerts/{alertId}/evidence:
|
||||
get:
|
||||
operationId: getAlertEvidence
|
||||
summary: Get evidence bundle for an alert
|
||||
tags:
|
||||
- Evidence
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/alertId'
|
||||
responses:
|
||||
'200':
|
||||
description: Evidence payload
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EvidencePayloadResponse'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/alerts/{alertId}/decisions:
|
||||
post:
|
||||
operationId: recordDecision
|
||||
summary: Record a decision for an alert
|
||||
tags:
|
||||
- Decisions
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/alertId'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DecisionRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: Decision recorded
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DecisionResponse'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
|
||||
/alerts/{alertId}/audit:
|
||||
get:
|
||||
operationId: getAlertAudit
|
||||
summary: Get audit timeline for an alert
|
||||
tags:
|
||||
- Audit
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/alertId'
|
||||
responses:
|
||||
'200':
|
||||
description: Audit timeline
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuditTimelineResponse'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/alerts/{alertId}/bundle:
|
||||
get:
|
||||
operationId: downloadAlertBundle
|
||||
summary: Download evidence bundle as tar.gz
|
||||
tags:
|
||||
- Bundles
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/alertId'
|
||||
responses:
|
||||
'200':
|
||||
description: Evidence bundle file
|
||||
content:
|
||||
application/gzip:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/alerts/{alertId}/bundle/verify:
|
||||
post:
|
||||
operationId: verifyAlertBundle
|
||||
summary: Verify evidence bundle integrity
|
||||
tags:
|
||||
- Bundles
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/alertId'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BundleVerificationRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Verification result
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BundleVerificationResponse'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
parameters:
|
||||
alertId:
|
||||
name: alertId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: Alert identifier
|
||||
|
||||
responses:
|
||||
BadRequest:
|
||||
description: Bad request
|
||||
content:
|
||||
application/problem+json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ProblemDetails'
|
||||
Unauthorized:
|
||||
description: Unauthorized
|
||||
NotFound:
|
||||
description: Resource not found
|
||||
|
||||
schemas:
|
||||
AlertListResponse:
|
||||
type: object
|
||||
required:
|
||||
- items
|
||||
- total_count
|
||||
properties:
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AlertSummary'
|
||||
total_count:
|
||||
type: integer
|
||||
next_page_token:
|
||||
type: string
|
||||
|
||||
AlertSummary:
|
||||
type: object
|
||||
required:
|
||||
- alert_id
|
||||
- artifact_id
|
||||
- vuln_id
|
||||
- severity
|
||||
- band
|
||||
- status
|
||||
- created_at
|
||||
properties:
|
||||
alert_id:
|
||||
type: string
|
||||
artifact_id:
|
||||
type: string
|
||||
vuln_id:
|
||||
type: string
|
||||
component_purl:
|
||||
type: string
|
||||
severity:
|
||||
type: string
|
||||
band:
|
||||
type: string
|
||||
enum: [critical, high, medium, low, info]
|
||||
status:
|
||||
type: string
|
||||
enum: [open, acknowledged, resolved, suppressed]
|
||||
score:
|
||||
type: number
|
||||
format: double
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
decision_count:
|
||||
type: integer
|
||||
|
||||
EvidencePayloadResponse:
|
||||
type: object
|
||||
required:
|
||||
- alert_id
|
||||
properties:
|
||||
alert_id:
|
||||
type: string
|
||||
reachability:
|
||||
$ref: '#/components/schemas/EvidenceSection'
|
||||
callstack:
|
||||
$ref: '#/components/schemas/EvidenceSection'
|
||||
vex:
|
||||
$ref: '#/components/schemas/EvidenceSection'
|
||||
|
||||
EvidenceSection:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
hash:
|
||||
type: string
|
||||
source:
|
||||
type: string
|
||||
|
||||
DecisionRequest:
|
||||
type: object
|
||||
required:
|
||||
- decision
|
||||
- rationale
|
||||
properties:
|
||||
decision:
|
||||
type: string
|
||||
enum: [accept_risk, mitigate, suppress, escalate]
|
||||
rationale:
|
||||
type: string
|
||||
minLength: 10
|
||||
maxLength: 2000
|
||||
justification_code:
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
|
||||
DecisionResponse:
|
||||
type: object
|
||||
required:
|
||||
- decision_id
|
||||
- alert_id
|
||||
- decision
|
||||
- recorded_at
|
||||
properties:
|
||||
decision_id:
|
||||
type: string
|
||||
alert_id:
|
||||
type: string
|
||||
decision:
|
||||
type: string
|
||||
rationale:
|
||||
type: string
|
||||
recorded_at:
|
||||
type: string
|
||||
format: date-time
|
||||
recorded_by:
|
||||
type: string
|
||||
replay_token:
|
||||
type: string
|
||||
|
||||
AuditTimelineResponse:
|
||||
type: object
|
||||
required:
|
||||
- alert_id
|
||||
- events
|
||||
- total_count
|
||||
properties:
|
||||
alert_id:
|
||||
type: string
|
||||
events:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AuditEvent'
|
||||
total_count:
|
||||
type: integer
|
||||
|
||||
AuditEvent:
|
||||
type: object
|
||||
required:
|
||||
- event_id
|
||||
- event_type
|
||||
- timestamp
|
||||
properties:
|
||||
event_id:
|
||||
type: string
|
||||
event_type:
|
||||
type: string
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
actor:
|
||||
type: string
|
||||
details:
|
||||
type: object
|
||||
replay_token:
|
||||
type: string
|
||||
|
||||
BundleVerificationRequest:
|
||||
type: object
|
||||
required:
|
||||
- bundle_hash
|
||||
properties:
|
||||
bundle_hash:
|
||||
type: string
|
||||
description: SHA-256 hash of the bundle
|
||||
signature:
|
||||
type: string
|
||||
description: Optional DSSE signature
|
||||
|
||||
BundleVerificationResponse:
|
||||
type: object
|
||||
required:
|
||||
- alert_id
|
||||
- is_valid
|
||||
- verified_at
|
||||
properties:
|
||||
alert_id:
|
||||
type: string
|
||||
is_valid:
|
||||
type: boolean
|
||||
verified_at:
|
||||
type: string
|
||||
format: date-time
|
||||
signature_valid:
|
||||
type: boolean
|
||||
hash_valid:
|
||||
type: boolean
|
||||
chain_valid:
|
||||
type: boolean
|
||||
errors:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
ProblemDetails:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
status:
|
||||
type: integer
|
||||
detail:
|
||||
type: string
|
||||
instance:
|
||||
type: string
|
||||
325
docs/api/smart-diff-types.md
Normal file
325
docs/api/smart-diff-types.md
Normal file
@@ -0,0 +1,325 @@
|
||||
# Smart-Diff API Types
|
||||
|
||||
> Sprint: SPRINT_3500_0002_0001
|
||||
> Module: Scanner, Policy, Attestor
|
||||
|
||||
This document describes the Smart-Diff types exposed through APIs.
|
||||
|
||||
## Smart-Diff Predicate
|
||||
|
||||
The Smart-Diff predicate is a DSSE-signed attestation describing differential analysis between two scans.
|
||||
|
||||
### Predicate Type URI
|
||||
|
||||
```
|
||||
stellaops.dev/predicates/smart-diff@v1
|
||||
```
|
||||
|
||||
### OpenAPI Schema Fragment
|
||||
|
||||
```yaml
|
||||
SmartDiffPredicate:
|
||||
type: object
|
||||
required:
|
||||
- schemaVersion
|
||||
- baseImage
|
||||
- targetImage
|
||||
- diff
|
||||
- reachabilityGate
|
||||
- scanner
|
||||
properties:
|
||||
schemaVersion:
|
||||
type: string
|
||||
pattern: "^[0-9]+\\.[0-9]+\\.[0-9]+$"
|
||||
example: "1.0.0"
|
||||
description: Schema version (semver)
|
||||
baseImage:
|
||||
$ref: '#/components/schemas/ImageReference'
|
||||
targetImage:
|
||||
$ref: '#/components/schemas/ImageReference'
|
||||
diff:
|
||||
$ref: '#/components/schemas/DiffPayload'
|
||||
reachabilityGate:
|
||||
$ref: '#/components/schemas/ReachabilityGate'
|
||||
scanner:
|
||||
$ref: '#/components/schemas/ScannerInfo'
|
||||
context:
|
||||
$ref: '#/components/schemas/RuntimeContext'
|
||||
suppressedCount:
|
||||
type: integer
|
||||
minimum: 0
|
||||
description: Number of findings suppressed by pre-filters
|
||||
materialChanges:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MaterialChange'
|
||||
|
||||
ImageReference:
|
||||
type: object
|
||||
required:
|
||||
- digest
|
||||
properties:
|
||||
digest:
|
||||
type: string
|
||||
pattern: "^sha256:[a-f0-9]{64}$"
|
||||
example: "sha256:abc123..."
|
||||
repository:
|
||||
type: string
|
||||
example: "ghcr.io/org/image"
|
||||
tag:
|
||||
type: string
|
||||
example: "v1.2.3"
|
||||
|
||||
DiffPayload:
|
||||
type: object
|
||||
required:
|
||||
- added
|
||||
- removed
|
||||
- modified
|
||||
properties:
|
||||
added:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/DiffEntry'
|
||||
description: New vulnerabilities in target
|
||||
removed:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/DiffEntry'
|
||||
description: Vulnerabilities fixed in target
|
||||
modified:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/DiffEntry'
|
||||
description: Changed vulnerability status
|
||||
|
||||
DiffEntry:
|
||||
type: object
|
||||
required:
|
||||
- vulnId
|
||||
- componentPurl
|
||||
properties:
|
||||
vulnId:
|
||||
type: string
|
||||
example: "CVE-2024-1234"
|
||||
componentPurl:
|
||||
type: string
|
||||
example: "pkg:npm/lodash@4.17.21"
|
||||
severity:
|
||||
type: string
|
||||
enum: [CRITICAL, HIGH, MEDIUM, LOW, UNKNOWN]
|
||||
changeType:
|
||||
type: string
|
||||
enum: [added, removed, severity_changed, status_changed]
|
||||
|
||||
ReachabilityGate:
|
||||
type: object
|
||||
required:
|
||||
- class
|
||||
- isSinkReachable
|
||||
- isEntryReachable
|
||||
properties:
|
||||
class:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description: |
|
||||
3-bit reachability class:
|
||||
- Bit 0: Entry point reachable
|
||||
- Bit 1: Sink reachable
|
||||
- Bit 2: Direct path exists
|
||||
isSinkReachable:
|
||||
type: boolean
|
||||
description: Whether a sensitive sink is reachable
|
||||
isEntryReachable:
|
||||
type: boolean
|
||||
description: Whether an entry point is reachable
|
||||
sinkCategory:
|
||||
type: string
|
||||
enum: [file, network, crypto, command, sql, ldap, xpath, ssrf, log, deserialization, reflection]
|
||||
description: Category of the matched sink
|
||||
|
||||
ScannerInfo:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- version
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: "stellaops-scanner"
|
||||
version:
|
||||
type: string
|
||||
example: "1.5.0"
|
||||
commit:
|
||||
type: string
|
||||
example: "abc123"
|
||||
|
||||
RuntimeContext:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
description: Optional runtime context for the scan
|
||||
example:
|
||||
env: "production"
|
||||
namespace: "default"
|
||||
cluster: "us-east-1"
|
||||
|
||||
MaterialChange:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum: [file, package, config]
|
||||
path:
|
||||
type: string
|
||||
hash:
|
||||
type: string
|
||||
changeKind:
|
||||
type: string
|
||||
enum: [added, removed, modified]
|
||||
```
|
||||
|
||||
## Reachability Gate Classes
|
||||
|
||||
| Class | Entry | Sink | Direct | Description |
|
||||
|-------|-------|------|--------|-------------|
|
||||
| 0 | ❌ | ❌ | ❌ | Not reachable |
|
||||
| 1 | ✅ | ❌ | ❌ | Entry point only |
|
||||
| 2 | ❌ | ✅ | ❌ | Sink only |
|
||||
| 3 | ✅ | ✅ | ❌ | Both, no direct path |
|
||||
| 4 | ❌ | ❌ | ✅ | Direct path, no endpoints |
|
||||
| 5 | ✅ | ❌ | ✅ | Entry + direct |
|
||||
| 6 | ❌ | ✅ | ✅ | Sink + direct |
|
||||
| 7 | ✅ | ✅ | ✅ | Full reachability confirmed |
|
||||
|
||||
## Sink Categories
|
||||
|
||||
| Category | Description | Examples |
|
||||
|----------|-------------|----------|
|
||||
| `file` | File system operations | `File.Open`, `fopen` |
|
||||
| `network` | Network I/O | `HttpClient`, `socket` |
|
||||
| `crypto` | Cryptographic operations | `SHA256`, `AES` |
|
||||
| `command` | Command execution | `Process.Start`, `exec` |
|
||||
| `sql` | SQL queries | `SqlCommand`, query builders |
|
||||
| `ldap` | LDAP operations | `DirectoryEntry` |
|
||||
| `xpath` | XPath queries | `XPathNavigator` |
|
||||
| `ssrf` | Server-side request forgery | HTTP clients with user input |
|
||||
| `log` | Logging operations | `ILogger`, `Console.Write` |
|
||||
| `deserialization` | Deserialization | `JsonSerializer`, `BinaryFormatter` |
|
||||
| `reflection` | Reflection operations | `Type.GetType`, `Assembly.Load` |
|
||||
|
||||
## Suppression Rules
|
||||
|
||||
### OpenAPI Schema Fragment
|
||||
|
||||
```yaml
|
||||
SuppressionRule:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- type
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique rule identifier
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- cve_pattern
|
||||
- purl_pattern
|
||||
- severity_below
|
||||
- patch_churn
|
||||
- sink_category
|
||||
- reachability_class
|
||||
pattern:
|
||||
type: string
|
||||
description: Regex pattern (for pattern rules)
|
||||
threshold:
|
||||
type: string
|
||||
description: Threshold value (for severity/class rules)
|
||||
enabled:
|
||||
type: boolean
|
||||
default: true
|
||||
reason:
|
||||
type: string
|
||||
description: Human-readable reason for suppression
|
||||
expires:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Optional expiration timestamp
|
||||
|
||||
SuppressionResult:
|
||||
type: object
|
||||
properties:
|
||||
suppressed:
|
||||
type: boolean
|
||||
matchedRuleId:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Creating a Smart-Diff Predicate
|
||||
|
||||
```csharp
|
||||
var predicate = new SmartDiffPredicate
|
||||
{
|
||||
SchemaVersion = "1.0.0",
|
||||
BaseImage = new ImageReference
|
||||
{
|
||||
Digest = "sha256:abc123...",
|
||||
Repository = "ghcr.io/org/image",
|
||||
Tag = "v1.0.0"
|
||||
},
|
||||
TargetImage = new ImageReference
|
||||
{
|
||||
Digest = "sha256:def456...",
|
||||
Repository = "ghcr.io/org/image",
|
||||
Tag = "v1.1.0"
|
||||
},
|
||||
Diff = new DiffPayload
|
||||
{
|
||||
Added = [new DiffEntry { VulnId = "CVE-2024-1234", ... }],
|
||||
Removed = [],
|
||||
Modified = []
|
||||
},
|
||||
ReachabilityGate = new ReachabilityGate
|
||||
{
|
||||
Class = 7,
|
||||
IsSinkReachable = true,
|
||||
IsEntryReachable = true,
|
||||
SinkCategory = SinkCategory.Network
|
||||
},
|
||||
Scanner = new ScannerInfo
|
||||
{
|
||||
Name = "stellaops-scanner",
|
||||
Version = "1.5.0"
|
||||
},
|
||||
SuppressedCount = 5
|
||||
};
|
||||
```
|
||||
|
||||
### Evaluating Suppression Rules
|
||||
|
||||
```csharp
|
||||
var evaluator = services.GetRequiredService<ISuppressionRuleEvaluator>();
|
||||
|
||||
var result = await evaluator.EvaluateAsync(finding, rules);
|
||||
|
||||
if (result.Suppressed)
|
||||
{
|
||||
logger.LogInformation(
|
||||
"Finding {VulnId} suppressed by rule {RuleId}: {Reason}",
|
||||
finding.VulnId,
|
||||
result.MatchedRuleId,
|
||||
result.Reason);
|
||||
}
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Smart-Diff Technical Reference](../product-advisories/14-Dec-2025%20-%20Smart-Diff%20Technical%20Reference.md)
|
||||
- [Scanner Architecture](../modules/scanner/architecture.md)
|
||||
- [Policy Architecture](../modules/policy/architecture.md)
|
||||
Reference in New Issue
Block a user