Reading results
Same severity scale, same triage workflow, regardless of which scanner produced the finding. NSO normalises everything before it reaches the UI.
Severity scale
| Severity | Meaning | Default SLA |
|---|---|---|
| Critical | Active or trivial RCE / authn bypass / data exposure. | Fix within 7 days. |
| High | Exploitable with prerequisites; sensitive data at risk. | Fix within 30 days. |
| Medium | Misconfig with realistic abuse path; needs chaining. | Fix within 90 days. |
| Low | Best-practice deviation, low impact. | Address at next maintenance. |
| Info | Informational, no action required. | Track only. |
What each scanner contributes
| Scanner | Surface | Typical findings |
|---|---|---|
| Edge Scan | External HTTP | TLS expiry, weak headers, CORS, exposed paths. |
| Nmap | Network | Open ports, service banners, host discovery. |
| Nuclei | Web / network | Template-driven CVE and misconfig checks. |
| ZAP | Web app | DAST: XSS, SQLi, broken auth, session issues. |
| Trivy | Containers / IaC | OS and library CVEs, IaC misconfig, secrets. |
Triage workflow
- Open the finding on /vulnerabilities.
- Read the description, evidence, and affected asset.
- Reproduce manually if confidence is below high.
- Decide: Fixed, Accepted (with expiry), or False positive (with reasoning).
- The transition is logged to
finding_status_history— never delete history.
Step-by-step: reading a completed scan
- Go to /scans and open the job. Confirm status is
completedand the finished timestamp is recent. - Check the Summary strip: counts by severity, duration, and the worker that ran it. A 0/0/0/0/0 result with a very short duration usually means the target was unreachable — see failure modes below.
- Click Findings. Sort by severity, then by asset. Group duplicates by
internal_idbefore triaging. - Open one finding. Read, in order: Description → Evidence (request/response, port banner, template match) → Affected asset → Remediation.
- Reproduce if confidence is not
high. Paste the evidence request intocurlor rerun the single Nuclei template. - Set status: Fixed, Accepted (with expiry + approver), or False positive (with reproduction notes).
- Click Download raw report if you need the untouched scanner output. The signed URL expires in 15 minutes — mint a new one rather than sharing.
- Re-queue the same profile after a fix and confirm the finding does not return.
Example outputs
Edge Scan
{
"internal_id": "tls_expiring_soon",
"severity": "medium",
"asset": "app.example.com",
"evidence": { "not_after": "2026-07-04T00:00:00Z", "days_left": 9 },
"remediation": "Renew certificate; auto-renewal appears stalled."
}Nmap
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1
3306/tcp open mysql MySQL 8.0.31 <-- exposed DB, expected internal onlyNuclei
[exposed-panels:grafana-detect] [http] [info] https://app.example.com/login
[CVE-2023-1234] [http] [high] https://app.example.com/api/v1/debugZAP
Alert: Reflected XSS
URL: https://app.example.com/search?q=%3Cscript%3E
Evidence: <script>alert(1)</script> reflected unescaped in response body
Risk: High Confidence: MediumTrivy
api:1.4.2 (alpine 3.18)
├─ openssl 3.1.1-r1 CVE-2023-5363 HIGH fixed in 3.1.2-r0
└─ libxml2 2.11.4-r0 CVE-2024-25062 MEDIUM fixed in 2.11.5-r0Common failure modes
| Symptom | Likely cause | Fix |
|---|---|---|
| Scan completes in < 5s with zero findings | Asset DNS TXT not verified, or target unreachable from worker network. | Check /assets verification panel; confirm worker egress. |
Scan stuck on queued | No worker leasing jobs for that profile / tenant. | Open /settings/workers, verify heartbeat < 60s. |
Scan ends as failed with timeout | Profile budget exceeded (long Nuclei/ZAP run). | Raise the profile timeout or narrow the template set. |
| Flood of identical findings on each run | Dedup by internal_id didn't match — usually evidence diff. | Mark one canonical, accept the rest as duplicates; file a normalisation bug. |
| "403" everywhere in ZAP/Nuclei evidence | WAF rate-limited the worker IP. | Allowlist the worker egress IP for scan windows, or throttle the profile. |
| Raw report download returns 404 / expired | Signed URL older than 15 min, or report deleted by retention. | Re-mint from the scan detail page; for retention, re-run the scan. |
| Common false positives | Nuclei version-banner CVEs against backported distros; ZAP XSS in non-rendered JSON. | Mark FP with the curl reproduction proving non-exploitability. |
Raw reports and download URLs
Each scan job stores its raw output in storage. From the scan detail page, click Download raw report — the app mints a short-lived signed URL. Do not share signed URLs externally; mint a fresh one when needed.
When to mark fixed vs ignore
- Fixed — underlying issue resolved; next scan should confirm.
- Accepted — risk acknowledged, with expiry and approver.
- False positive — finding doesn't apply; include reproduction notes so the next analyst doesn't redo the work.