Appearance
Findings
A finding is a vulnerability or issue discovered during a scan. Findings are how you triage scan output: mark what you've looked at, curate what goes into a report, export subsets, and delete noise.
Open a project and choose Findings in the sidebar for the full project list. The same findings table also appears on a host's Findings tab and on a scan's Findings tab in scan detail, with the same filters, row actions, and bulk actions (when a project context is available).
Where findings appear
| View | How to open it | Scope |
|---|---|---|
| Findings (sidebar) | Project → Findings | All findings in the project |
| Findings (host tab) | Host → Findings | Findings for that host only |
| Scan results | Scans, a tool page Scans list, a host tool tab, or Active Jobs → click a scan row | Findings from that scan only (scan detail Findings tab) |
LFIC and Bustah
Clicking an lfic or bustah row opens the same scan detail modal as Nikto and crawl. Results is the default tab: Bustah shows the tree in place; LFIC says the file explorer lives on the host LFIC tab. Use Host view to open the host's own workspace. Any finding rows from that scan still appear on the modal's Findings tab and on project/host Findings.
All three use the same table layout and controls. Report and reviewed toggles are available whenever you are inside a project (project Findings, host Findings, and scan detail opened from a project).
The findings table
Each row shows:
- URL — where the finding was discovered (or the host origin for a collapsed group).
- Severity —
critical,high,medium,low, orinfo, color-coded. - Title — a short description, or a group label such as Technologies detected (12).
- Actions — per-row buttons on the right (see below).
URL and Title are resizable: drag the right edge of the header, or tab to the grip and use Arrow Left / Arrow Right (hold Shift for a larger step). See Accessibility.
Click URL, Severity, or Title to sort the loaded table. Severity sorts by rank (worst first when ascending), not alphabetically. A third click returns to the default order (severity). Sorting a truncated list orders only the loaded rows — the orange banner says so.
Grouped findings
Crawl technology detection emits one info finding per product/version. To keep long crawl runs readable, matching rows collapse into a single expandable group per host — for example Technologies detected (12) showing https://example.com in the URL column.
- Click the group row to expand or collapse the member findings.
- The group checkbox is tri-state — selecting the group selects all members for bulk actions (Add to Report, Mark Reviewed, Export, Delete).
- Filters apply to members first; a group shrinks as its members are filtered out.
Other finding types appear as normal single rows.
Use Rows per page (25 / 50 / 100 / 500 / All) and Prev / Next at the bottom of the table when the list is long. Default page size is 100.
Visual cues on each row:
- Reviewed findings show a blue left border.
- Findings in the report show a green left border (both reviewed and in-report use a combined green + blue accent).
The header shows how many rows match the current filters. Sidebar and host-tab badges use the server total when the list is truncated (see below).
When only the first page of a large project/host list is loaded, an orange banner states how many findings exist in total vs how many are loaded — filters and pagination apply to the loaded set only. If a column sort is active, the banner adds: The column sort orders only these loaded rows — the ones not loaded were left out by the server's own order, not by this sort, so the top row is not necessarily the top row on this host.
On project and host Findings, Dedupe across scans is on by default (the scan Findings tab has no such checkbox — that list is already one scan). The same observation from several scans is one row, marked ×N plus the tool names (for example ×2 crawl, nikto). Hover: Reported by N scans (…). Actions apply to all of them. Row actions (reviewed, report, delete) reach every copy. Uncheck the box to see every scan's row. Nothing is deleted either way. A collapsed row is reviewed only when every copy is reviewed.
Lists auto-refresh every 15 seconds while open so new scan results and triage changes from other views appear without a manual reload. A refresh does not blank an already-loaded table, and it stays on the page you are on (it only moves if that page no longer exists).
If an action returns 404 (the finding was deleted elsewhere), the UI shows Finding no longer in database and drops the stale row on the next refresh.
Filter findings
Filters combine; selection and counts always reflect what's currently shown.
- Search — text box with optional scoped prefixes (terms are ANDed):
- Bare words match title, URL, tool, and rule/test ID.
title:,request:,response:,header:,tool:,id:search those fields (quote values with spaces, e.g.header:"set-cookie").- Clear with the ✕ control.
- Severity — colored chips (
3 critical,12 high, …). Click a chip to filter to that severity; click again to clear. - To triage — N To triage shows only findings that are not in the report and not yet reviewed — your working queue. One click sets both filters below; click again (or Clear) to show everything. Shown in a project context only, since report membership is what half of it means.
- Report — when at least one finding is in (or out of) the report:
- ✓ N In report — show only findings in the report.
- ✗ N Not in report — show only findings not in the report.
- Reviewed — when at least one finding is reviewed or unreviewed:
- 👁 N Reviewed — show only findings you have marked reviewed.
- ✗ N Unreviewed — show only findings still needing triage.
- Tool — dropdown to limit by tool (
nikto,lfic, …), shown when more than one tool is present.
Each chip shows the rows it names (it does not hide them), and each is a toggle: clicking the active chip clears it. While a filter is on, a line under the bar states what is being shown in words.
Triage workflow
Click To triage, work through the list, mark each finding Reviewed as you go, and Add to Report for anything that should go to stakeholders. Rows leave the list as you act on them; when the count reaches zero, triage is complete.
Filters are per-visit — leaving the view and coming back shows everything again.
Row actions
Each row has icon buttons (they do not open the detail view when clicked):
| Button | What it does |
|---|---|
| Eye / check | Toggle reviewed. Eye = not yet reviewed; green check = reviewed. Click again to unmark. |
| Bookmark+ / bookmark check | Toggle report membership. Add to the project's report, or remove (with confirmation). |
| Trash | Delete the finding permanently (with confirmation). |
The same actions appear in the finding detail footer when you open a row.
Finding detail
Click a row to open the detail modal: the target host (hostname or host:port) sits above the title, then severity, request/response, description, remediation, references, and tool-specific fields. The host line stays visible in Screenshot mode so a capture still names the target. The modal is resizable (drag the corner); request and response panes resize independently. Use Screenshot mode in the footer to hide chrome for a clean capture — any click restores controls. Footer reviewed and report toggles close the modal on success. A failed request leaves the modal open with the error. Close with Escape or the ✕.
A note above a pane says when that record is not a full wire capture. A finding with no note (including findings stored by earlier versions) makes no claim either way about fidelity.
| Note (starts with) | Meaning |
|---|---|
| Partial record | The browser sent the request; only method, URL, and any Authorization/Cookie headers were kept. More headers went out than are shown. Typical of crawl. |
| Header fields, not exact bytes | Recorded from the raw HTTP client used for deliberately malformed probes. Names, spacing, and the request line are normalized; the bytes on the wire may have been malformed on purpose. |
| Composed request | The request the scanner built for the check, not one captured on the wire. What was sent may differ. |
| Rendered page | The response body is the DOM after the browser ran the page's JavaScript, not the bytes the server returned. Headers and status are from the wire. Typical of a Headless crawl. |
Snippet evidence (a JWT lifted from a page, a matched secret) has no HTTP exchange behind it. That pane is labelled Evidence excerpt, not Response, and no status line is invented for it.
A response Content-Length header is the value the server sent. The stored body may be smaller (decoded or truncated); the header is not rewritten to match.
Copy as Curl
Copy as Curl above the request pane builds a command that reproduces the exchange. Probes that deliberately send an unusual request line are reproduced as sent, not as a tidied-up request to the same URL:
| Probe | What the command carries |
|---|---|
| Proxy-bypass probe (absolute URL in the request line) | -x <connected host:port> plus the absolute URL as the operand, so curl replays a proxy-form request. |
| HTTP/1.0 probe | --http1.0. These checks depend on the version. |
Malformed path (for example an invalid % escape) | --path-as-is --request-target, so curl sends the path unchanged. |
Probe that suppressed the Host header | -H 'Host;', so curl does not add one back. |
Where the request line was captured verbatim, the request pane shows those bytes. Where it was not, the pane rebuilds the line from the method, URL, and version — a reconstruction is never presented as verbatim.
Finding types
HTTP/2 and HTTP/3 findings
When a finding was captured over HTTP/2 or HTTP/3, the detail view shows reconstructed request/response text (these protocols have no HTTP/1.x-style request line on the wire). A note explains the framing (HPACK for HTTP/2, QUIC/QPACK for HTTP/3).
Toggle H3/H2 Pseudo Headers (default) vs HTTP/1.1 Style above the panes. Copy as Curl adds --http2 or --http3 when applicable. Full behavior, Alt-Svc workflow, and report formatting are covered in HTTP/3 scanning.
Outdated JavaScript libraries
Crawl scans may emit Outdated JavaScript library findings when a known-vulnerable script version is detected. When the platform can determine which pages loaded the script, the detail view shows a Loaded By section:
- Page — the site page that referenced the script
- Asset — the script URL (highlighted when served from a different host than the page)
The list is capped at 25 entries; the caption states when more pages loaded the library than are shown. Reconciled findings may also show authoritative version info and source URLs in a dedicated reconciliation block.
JWT findings
The JWT module emits one finding per token, keyed on where it lives (cookie, header, or body) and its algorithm — not once per page. A site-wide cookie therefore stays one JWT observed and decoded row (plus one row per proven check), even if the crawl hit it on hundreds of pages.
Additional Fields on that row lists seen_on (up to 20 page URLs) and seen_on_count (the total, which keeps rising after the list is truncated). A response body can contribute up to 5 tokens, one per algorithm.
The compact token, decoded header, and payload stay in finding detail for triage.
Outdated server software
Nikto compares the Server banner to a curated current-version list and emits a low finding per outdated product. The title names the full product span from the banner (for example a specific application server), not a nested generic Server/ token. Several products on one banner each get a finding. A match with no version after it produces none.
HTTP authentication realms
A 401 response names the realm the server uses for whatever sits behind the login. Each distinct realm produces one info finding, titled like:
HTTP authentication required (Basic) realm "dev1-mail"The scheme, realm, and URL are stored with the finding. Only 401 counts: a 407 is a proxy challenging the scanner rather than a fact about the target, and a WWW-Authenticate header on a 200 is advisory or already satisfied.
Findings are deduplicated by host + scheme + realm, not by URL. A protected area answers 401 on every path beneath it, and a crawl visits many of them; one realm stays one finding.
Each realm also raises a manual-only, advisory recommendation to run a credential attack against it — see Recommendations. Nikto already tries its default-credential list against every 401 during the scan; exhausting a realm with a full wordlist is noisy and can trigger account lockout, so that step is left to you.
TLS certificate findings
HTTPS fetches capture the handshake certificate. The scanner does not refuse a request because the cert is invalid — it records what it saw and continues. Findings are one per host (a cert is a property of the host:port, not each path):
| Finding | Severity | When |
|---|---|---|
| TLS certificate for host | info | Always — subject, issuer, SANs, validity window, version, cipher |
| Expired TLS certificate | medium | NotAfter is in the past |
| TLS certificate not yet valid | medium | NotBefore is in the future |
| Self-signed TLS certificate | medium | Issuer equals subject |
| Untrusted TLS certificate | medium | Other verification failure (hostname mismatch on a hostname dial, unknown CA) |
| TLS certificate expiring soon | low | Still valid, but NotAfter is within 30 days |
| Server is using a wildcard certificate: … | info | The certificate has a *. name in the SAN list or common name. A fact about the deployment, not a defect. |
A hostname mismatch on a request that dialed the host by IP is not reported as Untrusted TLS certificate. Several Nikto checks connect by address on purpose, and a normal public certificate has no IP SAN — that mismatch describes how the scanner reached the host, not a defect in the cert.
When the scan target is a hostname but the request dialed an IP (no SNI), the server often returns its default vhost certificate. Defect verdicts (expired, self-signed, untrusted) are not raised for that cert — they would describe the fallback, not this host. The info finding is titled TLS certificate for address (the IP that served it), so it does not occupy the hostname's own certificate row. Additional Fields includes cert_verdicts_suppressed with the reason, observed_while_scanning (the hostname you scanned), and dialed_by_ip when the request targeted an IP. A mismatch on a hostname dial, or an expired, self-signed, or untrusted-chain cert on a connection that used SNI, is still reported.
Certificate findings point at the origin (https://host[:port]), not the probe path that happened to trigger the handshake.
These appear on Nikto, crawl, and other tools that make HTTPS requests. A Headless Browser crawl sees the certificate through its own interception proxy, and the same rules produce the same findings there — including the IP-dial and default-vhost suppressions — so a crawl of an HTTPS host reports an expired or self-signed cert even when no Nikto scan ran. One finding per host, not per page.
The certificate's SHA-256 fingerprint is also written to the host's own intel (Tls Cert Sha256 under Host info → Other), which survives deleting the scan — so you can tell whether a host's certificate changed between scans. See Hosts → Overview.
Tomcat Manager (access-restricted)
A Tomcat Manager or Host Manager webapp that answers 403 with Tomcat's own denial page (it mentions conf/tomcat-users.xml) produces a low finding:
Tomcat Manager is deployed but access-restricted (HTTP 403)That is evidence the app is installed and reachable, not that it is open or using default credentials. Manager and Host Manager are separate rows. Paths under the same app (/manager/html, /manager/status) stay one finding. A 200 on those paths is the unrestricted case and is reported by the usual Nikto checks instead.
FortiGate, JasperServer, and X-Frame-Options
Nikto also reports:
- FortiGate administrative web interface — a login redirect that identifies the FortiGate admin UI.
- FortiOS SSL VPN login — including a box that redirects to the VPN login instead of serving the login page markup.
- JasperServer version disclosure — unauthenticated
/jasperserver-pro/rest_v2/serverInfothat returns build and feature details. - X-Frame-Options present — the header is still sent (it is deprecated in favour of CSP
frame-ancestors). This fires when the header is there, not when it is missing.
Cloud storage listing findings
An anonymous S3, S3-compatible, or Azure Blob Storage listing produces a medium finding (S3 Bucket Listing Enabled or Azure Blob Container Listing Enabled). The description has the bucket/container, how far the scan walked, and sample object URLs. If a listing page was cut off by the response size limit, the description says so and the counts are a floor — that is not the 5-page scan cap. A matching recommendation titled Cloud Storage: Export full file list (button Export full file list) walks the entire listing. See Cloud Storage Listings.
Secret detection findings
When Secret Detection is enabled on a scan, matching credentials in response bodies appear as informational findings. Values are stored unredacted in the detail view so you can identify and rotate leaked keys. The end-of-scan scan statistics finding redacts passwords, cookie/header values, and similar secrets from the stored options snapshot so that summary is safe to share.
Request counts on that finding come from each tool's own record. Scan Statistics shows Requests Source; when the activity log is not the source, Activity Rows Logged shows the gap. A missing status breakdown is Status Classes Complete false plus Status Classes Unavailable Reason — not an empty Status Classes map that looks like “no responses”.
Low-confidence matches may be dropped. Unscored matches are always kept.
Removing from the report or deleting a finding does not affect the underlying scan; it only changes which findings you keep or include.
Select and bulk actions
Use checkboxes to select rows, or the header checkbox to select everything currently filtered. With one or more selected, bulk buttons appear:
- Add to Report N — add all selected findings to the project report. If some cannot be filed (host not in a project) or no longer exist, a red line reports Report: added N of M; N could not be added; N no longer exist. plus any named reasons. Skipped rows are not marked in-report; the selection stays so you can retry. A single bookmark+ that cannot be filed shows the refusal reason instead of looking like success.
- Mark Reviewed N — mark all selected as reviewed.
- Export N — download selected findings as CSV or JSON. See Exporting Findings.
- Delete N — permanently remove selected findings (with confirmation).
Reviewed vs. report
These are separate concepts:
| State | Meaning |
|---|---|
| Reviewed | You have looked at this finding during triage. Helps you track progress and filter out finished work. Does not remove the finding or change the scan. |
| In report | This finding is snapshotted into the project's Report as an item with HTTP evidence. LFI Commander files are added separately from the LFIC results tree — see Add files to the report. |
Next steps
- Build your report
- Export findings to CSV or JSON
- Cloud Storage Listings — S3 / Azure Blob listing findings
- Recommendations — export a full object list
- Audit the activity log