Origem: D:/Documents/Github/dev-workflows Arquivos omitidos (segredos, bancos de dados, logs, >50 MB): 0
230 lines
7.8 KiB
Markdown
230 lines
7.8 KiB
Markdown
# SARIF Output Mapping
|
|
|
|
SecuritySkills may emit SARIF-compatible JSON for tools that ingest Static
|
|
Analysis Results Interchange Format (SARIF) 2.1.0. SARIF output is an export
|
|
view of the normalized finding envelope documented in
|
|
[`docs/normalized-json-output.md`](normalized-json-output.md); it does not
|
|
replace the normalized JSON contract or change the required finding fields.
|
|
|
|
## Top-Level Shape
|
|
|
|
Use SARIF version `2.1.0` with the standard schema URI:
|
|
|
|
```json
|
|
{
|
|
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
|
|
"version": "2.1.0",
|
|
"runs": [
|
|
{
|
|
"tool": {
|
|
"driver": {
|
|
"name": "SecuritySkills",
|
|
"semanticVersion": "1.0.0",
|
|
"rules": []
|
|
}
|
|
},
|
|
"results": []
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Use one `run` per normalized envelope. `run.tool.driver.name` should identify
|
|
SecuritySkills or the executing agent. `run.tool.driver.semanticVersion` should
|
|
use the skill version when a single skill produced the run.
|
|
|
|
## Mapping
|
|
|
|
Map normalized fields to SARIF as follows:
|
|
|
|
| Normalized field | SARIF field |
|
|
|---|---|
|
|
| `run.id`, `run.timestamp`, `run.target`, `run.source_ref` | `runs[].properties.securityskills.run` |
|
|
| `skill.name`, `skill.version`, `skill.path`, `skill.frameworks` | `runs[].tool.driver.name`, `runs[].tool.driver.semanticVersion`, `runs[].properties.securityskills.skill` |
|
|
| `finding.id` | `results[].ruleId` and `results[].properties.securityskills.finding_id` |
|
|
| `finding.fingerprint` | `results[].partialFingerprints.securityskillsFingerprint` |
|
|
| `finding.title` | `tool.driver.rules[].shortDescription.text` |
|
|
| `finding.description` | `tool.driver.rules[].fullDescription.text` and `results[].message.text` |
|
|
| `finding.severity` | `results[].level` |
|
|
| `finding.status` | `results[].properties.securityskills.status` |
|
|
| `finding.cwe` | `tool.driver.rules[].relationships` when supported, and `properties.securityskills.cwe` |
|
|
| `finding.framework_refs` | `tool.driver.rules[].properties.securityskills.framework_refs` |
|
|
| `finding.evidence` | `results[].locations` plus `properties.securityskills.evidence` |
|
|
| `finding.references` | `tool.driver.rules[].helpUri` or `tool.driver.rules[].properties.securityskills.references` |
|
|
| `finding.remediations` | `tool.driver.rules[].help.text` and `properties.securityskills.remediations`, including each remediation's `test_strategy` |
|
|
|
|
## Severity
|
|
|
|
SARIF `level` has fewer values than the normalized contract. Use this mapping:
|
|
|
|
| Normalized severity | SARIF level |
|
|
|---|---|
|
|
| `critical` | `error` |
|
|
| `high` | `error` |
|
|
| `medium` | `warning` |
|
|
| `low` | `note` |
|
|
| `info` | `note` |
|
|
|
|
Keep the original severity in
|
|
`results[].properties.securityskills.severity` so downstream systems can
|
|
preserve the distinction between `critical` and `high`.
|
|
|
|
## Locations
|
|
|
|
For source, configuration, policy, or scan-result evidence with file locations,
|
|
populate `results[].locations[].physicalLocation`:
|
|
|
|
```json
|
|
{
|
|
"physicalLocation": {
|
|
"artifactLocation": {
|
|
"uri": "routes/users.js"
|
|
},
|
|
"region": {
|
|
"startLine": 42
|
|
}
|
|
},
|
|
"message": {
|
|
"text": "DELETE /users/:id checks authentication but not administrator role."
|
|
}
|
|
}
|
|
```
|
|
|
|
If the normalized evidence location does not contain a parseable file path and
|
|
line number, still emit a SARIF result and store the original location under
|
|
`properties.securityskills.evidence`. For cloud resources, identities, network
|
|
assets, logs, or documents, use the best stable asset identifier as
|
|
`artifactLocation.uri` only when it is meaningful to the SARIF consumer.
|
|
|
|
## Rules
|
|
|
|
Create one `tool.driver.rules[]` entry per distinct `ruleId`. A rule should
|
|
include:
|
|
|
|
- `id`: the normalized `finding.id`, or a stable detector ID when multiple
|
|
findings share the same detection rule.
|
|
- `shortDescription.text`: the finding title or detector title.
|
|
- `fullDescription.text`: the finding description.
|
|
- `help.text`: remediation guidance and test strategy summary.
|
|
- `properties.securityskills`: CWE IDs, framework references, normalized
|
|
severity, and any remediation metadata that does not fit native SARIF fields.
|
|
|
|
Do not invent CWE, framework, or control identifiers for SARIF. Reuse only the
|
|
values already present in the normalized finding.
|
|
|
|
## Minimal Example
|
|
|
|
```json
|
|
{
|
|
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
|
|
"version": "2.1.0",
|
|
"runs": [
|
|
{
|
|
"tool": {
|
|
"driver": {
|
|
"name": "api-security",
|
|
"semanticVersion": "1.0.0",
|
|
"rules": [
|
|
{
|
|
"id": "API-SEC-001",
|
|
"shortDescription": {
|
|
"text": "Administrative endpoint lacks authorization check"
|
|
},
|
|
"fullDescription": {
|
|
"text": "The delete-user route accepts authenticated requests without verifying administrative privileges."
|
|
},
|
|
"help": {
|
|
"text": "Require an administrator role check before invoking deleteUser. Validate with integration tests for non-admin and admin delete flows."
|
|
},
|
|
"properties": {
|
|
"securityskills": {
|
|
"severity": "high",
|
|
"cwe": ["CWE-862"],
|
|
"framework_refs": [
|
|
{
|
|
"framework": "OWASP-API-Top-10-2023",
|
|
"control": "API5:2023",
|
|
"name": "Broken Function Level Authorization"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"results": [
|
|
{
|
|
"ruleId": "API-SEC-001",
|
|
"level": "error",
|
|
"message": {
|
|
"text": "Administrative endpoint lacks authorization check"
|
|
},
|
|
"locations": [
|
|
{
|
|
"physicalLocation": {
|
|
"artifactLocation": {
|
|
"uri": "routes/users.js"
|
|
},
|
|
"region": {
|
|
"startLine": 42
|
|
}
|
|
},
|
|
"message": {
|
|
"text": "DELETE /users/:id checks authentication but not administrator role."
|
|
}
|
|
}
|
|
],
|
|
"partialFingerprints": {
|
|
"securityskillsFingerprint": "api-security:users-delete:missing-admin-auth"
|
|
},
|
|
"properties": {
|
|
"securityskills": {
|
|
"finding_id": "API-SEC-001",
|
|
"severity": "high",
|
|
"status": "open",
|
|
"remediations": [
|
|
{
|
|
"guidance": "Require an administrator role check before invoking deleteUser.",
|
|
"confidence": "high",
|
|
"blast_radius": "User administration routes only.",
|
|
"behavior_change_risk": "medium",
|
|
"test_strategy": {
|
|
"summary": "Proves non-admin users cannot delete accounts while admins still can.",
|
|
"recommended_tests": [
|
|
{
|
|
"name": "Reject non-admin delete",
|
|
"type": "integration",
|
|
"purpose": "Confirms the authorization bypass no longer succeeds.",
|
|
"command": "npm test -- users-authz.test.js",
|
|
"expected_result": "Non-admin DELETE returns 403 and admin DELETE succeeds."
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"properties": {
|
|
"securityskills": {
|
|
"run": {
|
|
"id": "run-001",
|
|
"timestamp": "2026-06-16T12:00:00Z",
|
|
"target": "payments-api",
|
|
"source_ref": "abc1234"
|
|
},
|
|
"skill": {
|
|
"name": "api-security",
|
|
"version": "1.0.0",
|
|
"path": "skills/appsec/api-security/SKILL.md",
|
|
"frameworks": ["OWASP-API-Top-10-2023", "CWE"]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|