Vulnerabilities

A finding as a structured, defensible object — CVSS 4.0 and CWE taxonomy, deterministic validation, SLAs, sealed evidence, retest, quality gates and export.

What a finding is

A vulnerability is a structured, defensible object the agents store during a pentest — closer to a ticket than a scanner line. It carries taxonomy, a validation verdict, a triage lifecycle, evidence and provenance. You can assign it, comment on it, resolve it and reopen it; every change is recorded.

{
  "id": 42,
  "title": "SQL injection in /api/login",
  "severity": "critical",
  "status": "open",
  "validation_status": "validated",
  "cvss_version": "4.0",
  "cvss_vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
  "cvss_base_score": 9.3,
  "cwe_id": "CWE-89",
  "cve_ids": ["CVE-2023-1234"],
  "mitre_attack_techniques": ["T1190"],
  "finding_fingerprint": "c9b1…",
  "affected_endpoint": "/api/login",
  "affected_parameter": "username"
}

Taxonomy

severity is critical, high, medium, low or info. It may be derived from CVSS 4.0: the discovering LLM supplies the metrics; code computes the score and vector. If you override a CVSS-derived severity you must set severity_override_reason.

FieldMeaning
cwe_idWeakness, CWE-89
cve_idsRelated CVEs
mitre_attack_techniquesATT&CK ids (T1190, T1110.001)
owasp_wstg_ids, owasp_asvs_idsTesting / ASVS control ids
epss_score, cisa_kevPublished exploitability signals (FIRST EPSS, CISA KEV). Not writable on PATCH — they stay checkable against the publishers.
finding_fingerprintStable identity for dedup and regression across runs. Computed by the API; you do not send it.
affected_asset / affected_endpoint / affected_parameterWhere the issue lives
reproduction_steps, request_responseHow to replay it
reference_urlsExternal references

Independently, you still control priority (urgent, high, normal, low) for your own queue.

Validation

validation_status is how much the finding can be trusted as a confirmed issue:

StatusMeaning
unvalidatedStored, awaiting a verdict
validatedReproduced by a deterministic validator
failedPositively refuted — the issue is not present
needs_manual_reviewA validator applied but could not conclude
not_validatableNo deterministic validator for this class
legacyHistoric finding from before validation existed; trusted as-is

Validators are isolated from the discovering LLM. The confidence score is derived from which validator ran, not invented by the model.

Out-of-band classes (SSRF, XXE, deserialization) stay not_validatable — there is no OOB collaborator to prove them automatically.

Human review is POST /pentests/{id}/vulnerabilities/{vulnId}/review. It is allowed only from needs_manual_review or not_validatable, and only to validated or failed. It is not a way to walk back an already recorded conclusion.

Lifecycle states

Triage state is independent of validation. A vulnerability is always in exactly one of five states:

StateMeaning
openNewly detected, not yet triaged
in_progressSomeone is actively working on it
resolvedFixed and closed
false_positiveDetermined not to be a real issue (requires a reason)
accepted_riskAcknowledged but intentionally not fixed

The allowed transitions are:

FromTo
openin_progress, resolved, false_positive, accepted_risk
in_progressopen, resolved, false_positive, accepted_risk
resolvedopen (reopen)
false_positiveopen (reopen)
accepted_riskopen (reopen)

Resolving can be done with evidence (evidenced, which requires at least one uploaded file) or without evidence (without_evidence). Marking something a false positive requires a written reason.

SLAs and due dates

A due date starts only for validated or legacy findings. unvalidated, needs_manual_review and not_validatable do not start the clock — they never count as overdue.

Defaults (configurable via the remediation policy):

SeverityDefault SLA
Critical24 hours
High168 hours (7 days)
Medium720 hours (30 days)
Low2160 hours (90 days)
InfoNone

The due date is set once; a later verdict does not move it. A failed validation clears it. Reopening recomputes it, except for a refuted finding, which reopens with no clock. Findings past their due date count as overdue in the pentest summary and in quality gates.

Evidence

Three layers, with different jobs:

  1. Triage evidence-files — files you attach to back an evidenced resolution (images, PDF, TXT, CSV).
  2. Sealed artifacts — captured at discovery time, hashed over the real bytes, then confirmed. These are the defensible proof in a report.
  3. Provenance — which agent, model and tools produced the finding.

See Evidence & audit for artifacts, the signed manifest and the hashed audit chain.

Retest

A retest is a separate run against a resolved finding. It does not rewrite validation_status — the original verdict that the issue existed stays. The retest result is one of:

ResultEffect
fixedStays resolved
still_vulnerableReopens the finding (open)
inconclusiveStays resolved; could not conclude
skippedStays resolved (for example OOB / not_validatable)

See Retest & remediation.

Quality gates

For CI/CD, a quality gate evaluates rules against the current findings and returns pass/fail. A failing gate can block a deploy.

Always-on rule types: severity + max_open, min_resolution_rate (0–1), max_overdue. Opt-in, on top of those: min_verified_resolution_rate, max_unverified_resolved, max_regressed, max_pending_retests.

{
  "rules": [
    {"severity": "critical", "max_open": 0},
    {"min_resolution_rate": 0.8},
    {"max_overdue": 0},
    {"min_verified_resolution_rate": 0.9},
    {"max_unverified_resolved": 0},
    {"max_regressed": 0},
    {"max_pending_retests": 0}
  ]
}

Export

Download every finding as csv, json, sarif or defectdojo. SARIF and DefectDojo are finding exports, not report formats.

Assignment, comments and history

When a pentest belongs to a team, findings can be assigned to a member. Assigning an open finding moves it to in_progress. The assignee is notified by email on assignment, resolution and other key events.

Comments appear in a combined activity feed alongside system entries. History is an immutable audit trail of every status change.

Go deeper