Skip to content

feat(materials): add OVERSECURED_JSON material type for Oversecured mobile scan reports #3369

Description

@migmartri

Summary

Add a first-class material type for Oversecured scan reports so mobile (Android/iOS) results can be attested and policy-evaluated like any other scanner output.

Today the only way to bring an Oversecured report into an attestation is the generic EVIDENCE kind with a hand-written chainloop.material.evidence.id wrapper. That works, but it pushes the wrapping onto every caller, skips validation at craft time, and gives the UI nothing to key off.

About the tool

Oversecured is a commercial SAST + DAST scanner built for mobile binaries only (~175 Android / ~85 iOS vulnerability classes). It has a REST API and a CLI, and exports a scan report in json, csv, md and pdfthere is no SARIF output, so it can't be routed through the existing SARIF kind.

Obtaining the report:

oversecured report <scanId> --app <appId> --format json
# or
GET /workspaces/{workspaceId}/apps/{appId}/scans/{scanId}/export?format=json

Report shape

The per-finding fields worth relying on:

FieldNotes
category.severityhigh | medium | low — severity lives on the category, not the instance
category.idStable category UUID — the natural rule id
category.descriptionTitle / descriptionTextTitle and description of the vulnerability class
category.descriptionRemediationRemediation guidance
category.platformandroid | ios
hasSast / hasDastHow the finding was reached; DAST means reproduced on the running app
sources[] / sinkTaint flow, {code, file?, line}. Empty/null for config-only findings
code[]Decompiled snippets, lines[].is_matched marks the offending lines
folderIdTriage bucket; the system false_positives folder is one of them
llmDescriptionAI write-up: impact, howToFix[], CVSS-style vector, tags
hashDocumented as a stable identity across scans (detail endpoint)

Proposed work in this repo

  • app/controlplane/api/workflowcontract/v1/crafting_schema.proto — add OVERSECURED_JSON = 43 (next free value)
  • app/controlplane/api/workflowcontract/v1/crafting_schema_validations.go
  • pkg/attestation/crafter/materials/oversecured.go + test, following the shape of gitleaks.go: read the file, confirm it parses as an Oversecured report, then uploadAndCraft
  • register the crafter in pkg/attestation/crafter/materials/materials.go
  • regenerate the jsonschema / TS artifacts and add the row to the material types docs table

Format detection

Validate the export envelope, and when findings are present require the first one to carry a category with a severity in {high, medium, low} and a non-empty descriptionTitle. An empty report must be accepted — a clean scan is the common CI case and rejecting it would break passing pipelines.

One thing to confirm against a real export before implementing: the published docs describe the GET …/vulnerabilities list item and the single-finding detail response, but not the exact top-level envelope that export?format=json returns. The detection heuristic should be pinned to whatever that envelope actually is.

Making it work with SAST evaluation

The material type on its own doesn't make the report evaluable — the sast policy needs a new execution path (- kind: OVERSECURED_JSON) whose rego maps Oversecured findings onto the structured finding shape that family already consumes (message, rule_id, severity, severity_score, location, recommendation). Suggested mapping:

  • severity_score: high → 7.5, medium → 5.5, low → 2.0, lining up with the existing severity_score_map
  • rule_id: category.id
  • message: category.descriptionTitle
  • location: sink.file:sink.line, falling back to the first code[].file containing an is_matched line
  • recommendation: category.descriptionRemediation
  • skip findings sitting in the system false_positives folder, so the tool's own triage is honoured
  • consider an input to count only DAST-confirmed findings (hasDast), which Oversecured's own --fail-on can't express since it is severity-only and includes findings triaged as false positives

Worth noting for whoever writes that rego: Oversecured findings carry neither CWE nor CVE identifiers, so the cwe-top25 and owasp-top10-* families will never match them. sast is the right home, and the only one.

The material type also needs syncing into the platform-side enum and the evidence UI mapping, tracked separately.

🤖 Posted by Maximus bot (Claude Code) on behalf of @migmartri

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions