# nuclei: template-based vulnerability scanning in a pentest

> How to install and run nuclei, tune severity and rate limits, read its JSONL output, and how Tandera turns each match into a deduplicated finding.

`nuclei` sends requests defined by YAML templates and reports matches. It is not a crawler or a fuzzer — it checks for specific, known conditions: a CVE with a reliable signature, an exposed `.git` directory, a default credential, a misconfigured header. The value is entirely in the template corpus, which is community-maintained and large.

## Install

```bash
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
nuclei -update-templates
```

Templates live in `~/.local/nuclei-templates` and update independently of the binary. Update them before every engagement, not once a quarter.

## Core commands

```bash
# scan a live-host list
nuclei -l live.txt -silent

# only what you would actually report
nuclei -l live.txt -severity critical,high,medium -silent

# a specific template set
nuclei -l live.txt -tags cve,exposure -silent
nuclei -l live.txt -t http/exposures/ -silent

# JSONL for import
nuclei -l live.txt -severity critical,high -jsonl -o nuclei.jsonl

# be polite to production
nuclei -l live.txt -rate-limit 20 -concurrency 10 -timeout 10
```

## Output

```json
{"template-id":"git-config","info":{"name":"Git Config Exposure","severity":"medium",
 "classification":{"cve-id":null,"cwe-id":["cwe-200"]}},
 "type":"http","host":"https://example.com","matched-at":"https://example.com/.git/config",
 "timestamp":"2026-08-29T10:04:11Z"}
```

`matched-at` is the field that matters for the report — it is the exact URL you re-verify by hand.

## Where it sits in Tandera

nuclei runs in the **active_scan** phase of `recon_web_full` only. It is excluded from `recon_web_lite` by design: that flow is capped at a `NonIntrusive` risk ceiling and nuclei sends real payloads.

Tandera also ships a `nuclei.yaml` finding catalogue (`code/src/tandera-finding-catalog/catalog/nuclei.yaml`) that maps template IDs onto canonical finding definitions. That mapping is what turns `git-config` fired on twelve hosts into one deduplicated finding with twelve pieces of evidence, rather than twelve rows in a report.

## Using it in a pentest

**Rate-limit it against production.** The default concurrency will generate a spike your client's SOC notices. `-rate-limit 20` is a reasonable opening position; agree it with the client beforehand and note it in the methodology section.

**Templates have false positives, and you own them.** Every nuclei match goes in the report over your signature, not the template author's. Re-verify anything you intend to report — `matched-at` gives you the exact request to reproduce.

**Severity is the template author's opinion.** It reflects the class of issue, not the risk to this client on this host. Re-rate against real exposure and exploitability before it reaches the deliverable.

**Do not run the whole corpus by default.** Thousands of templates against a large host list is slow and noisy. Start with `-tags cve,exposure,misconfig` and widen deliberately.

---

Canonical: https://tandera.io/tools/nuclei
This page as markdown: https://tandera.io/tools/nuclei.md
Index for agents: https://tandera.io/llms.txt

Every page here is also available as markdown: append `.md` to the path (e.g. `/recon.md`, `/index.md` for this homepage, `/blog/<slug>.md`), or request the canonical path with `Accept: text/markdown`.
