Nuclei scanner
Build, extend, and operate Nuclei — a fast, template-based vulnerability scanner by ProjectDiscovery. Use when running automated vulnerability scans, writing custom detection templates, or building recon pipelines with subfinder and httpx. Covers installation, template structure (id, info, requests, matchers, extractors), scan execution flags, template selection by tag and severity, rate limiting, output formats, headless scanning, interactsh OOB integration, workflow chaining, and the subfinder → httpx → nuclei pipeline.From its SKILL.md
npx -y skills add jph4cks/redhound-arsenal --skill nuclei-scannerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
13.6 KB, ~3.6k tokens by cl100k_base, as published. Nobody here has run it
nuclei-scanner Agent Skill
When to Use This Skill
Use this skill when:
- Running automated vulnerability scans against web applications or infrastructure
- The user asks about Nuclei, nuclei templates, or ProjectDiscovery tooling
- Writing custom YAML templates to detect specific vulnerabilities or misconfigurations
- Building reconnaissance pipelines (subfinder → httpx → nuclei)
- Performing OOB (out-of-band) vulnerability detection with interactsh
- Tuning scan performance (rate limiting, concurrency, retries)
What Nuclei Does
Nuclei is a fast, configurable vulnerability scanner driven by YAML templates. Each template describes a specific check — HTTP request, DNS query, TCP probe, or headless browser action — along with matchers that determine a positive finding. The public template library covers thousands of CVEs, misconfigurations, exposures, and technology fingerprints. Teams use Nuclei to operationalize security checks as version-controlled, shareable YAML files.
Installation
# Go install (recommended — always latest)
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# Prebuilt binary (Linux amd64)
wget https://github.com/projectdiscovery/nuclei/releases/latest/download/nuclei_linux_amd64.zip
unzip nuclei_linux_amd64.zip && sudo mv nuclei /usr/local/bin/
# Kali / Debian (may lag behind latest)
sudo apt install nuclei
# macOS
brew install nuclei
# Docker
docker pull projectdiscovery/nuclei:latest
docker run --rm -v $(pwd):/data projectdiscovery/nuclei \
-u https://target.example.com -t /root/nuclei-templates/
# Update templates after install
nuclei -ut # update to latest community templates
nuclei -version
Template Structure
Every Nuclei template is a YAML file with these top-level keys:
id: template-unique-id # lowercase, hyphens, unique across all templates
info:
name: Human Readable Name
author: operator
severity: critical # info, low, medium, high, critical
description: What this detects and why it matters.
reference:
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-41773
tags: apache,rce,cve,cve2021 # comma-separated tags for filtering
metadata:
cvss-score: 9.8
cve-id: CVE-2021-41773
cwe-id: CWE-22
# Protocol-specific block: http, dns, tcp, headless, ssl, websocket, whois
http:
- method: GET
path:
- "{{BaseURL}}/cgi-bin/.%2e/.%2e/bin/sh"
headers:
Content-Type: application/x-www-form-urlencoded
body: "echo Content-Type: text/plain; echo; id"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
words:
- "uid="
- "gid="
condition: and
Template Variables
{{BaseURL}} # https://example.com/path
{{Hostname}} # example.com
{{Host}} # example.com (no port)
{{Port}} # 443
{{Scheme}} # https
{{randstr}} # Random string per request
{{randint}} # Random integer
{{unix_time}} # Current Unix epoch
# DSL helpers: contains(), len(), regex(), to_lower(), md5(), base64(), url_encode()
Matchers
matchers:
# Status code
- type: status
status:
- 200
- 302
# Word match (in body by default)
- type: word
words:
- "root:x:0:0"
case-insensitive: true
part: body # body, header, all, interactsh_protocol
# Regex match
- type: regex
regex:
- "([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})"
group: 1 # capture group to extract
# Binary match (for non-text responses)
- type: binary
binary:
- "504B0304" # PK ZIP magic bytes (hex)
# Size match
- type: size
size:
- 1024
# DSL expression match
- type: dsl
dsl:
- "contains(body, 'uid=0') && status_code == 200"
- "len(body) > 100"
condition: or
# Combine matchers
matchers-condition: and # all must match (default)
matchers-condition: or # any must match
Extractors
extractors:
- type: regex
name: api_key
regex:
- "api[_-]?key[\"']?\\s*[:=]\\s*[\"']?([A-Za-z0-9_\\-]{32,})"
group: 1
part: body
- type: kval
kval:
- Set-Cookie
- type: json
name: token
json:
- ".data.token"
- type: dsl
dsl:
- "concat(host, ':', port)"
Running Scans
Basic Usage
# Single target
nuclei -u https://target.example.com
# Target list
nuclei -l targets.txt
# Target list with specific templates
nuclei -l targets.txt -t cves/
# Single template
nuclei -u https://target.example.com -t cves/2021/CVE-2021-41773.yaml
# Template directory
nuclei -u https://target.example.com -t exposures/configs/
# Read targets from stdin
cat targets.txt | nuclei -t cves/
echo "https://target.example.com" | nuclei -t cves/2022/
Template Selection
# By tags (AND logic by default)
nuclei -u https://target.example.com -tags cve
nuclei -u https://target.example.com -tags apache,rce
nuclei -u https://target.example.com -tags "cve,2021"
# By severity
nuclei -l targets.txt -severity critical,high
nuclei -l targets.txt -severity medium
# Exclude tags
nuclei -l targets.txt -exclude-tags dos,fuzz,intrusive
# Exclude templates by path
nuclei -l targets.txt -exclude-templates fuzzing/
# By author
nuclei -l targets.txt -author pdteam
# Combine: critical CVEs, no DoS
nuclei -l targets.txt -severity critical -tags cve -exclude-tags dos
# Automatic scan (Nuclei picks templates based on detected tech)
nuclei -u https://target.example.com -as
Template Update
nuclei -ut # update to latest public templates
nuclei -ut -duc # update and disable update check banner
Rate Limiting and Concurrency
nuclei -l targets.txt -rl 100 # rate limit: 100 requests/sec (global)
nuclei -l targets.txt -c 25 # concurrent template executions (default 25)
nuclei -l targets.txt -bs 50 # bulk target size per template
nuclei -l targets.txt -rlm 10 # rate limit per minute
nuclei -l targets.txt -timeout 10 # per-request timeout in seconds
nuclei -l targets.txt -retries 2 # retry failed requests
# Conservative scan for sensitive targets
nuclei -l targets.txt -rl 10 -c 5 -timeout 15 -retries 1
Output Formats
nuclei -l targets.txt -o results.txt # plain text
nuclei -l targets.txt -json -o results.jsonl # JSON lines (one JSON per finding)
nuclei -l targets.txt -json-export results.json # single JSON array
nuclei -l targets.txt -me results/ # markdown export (per-host reports)
nuclei -l targets.txt -sarif-export results.sarif # SARIF for CI/CD integration
nuclei -l targets.txt -silent # suppress banner, print findings only
nuclei -l targets.txt -nc # no color output
nuclei -l targets.txt -v # verbose (show sent/received)
nuclei -l targets.txt -debug # print full request/response
nuclei -l targets.txt -stats # periodic progress stats
Headless Scanning (Browser-Based)
For JavaScript-heavy applications and DOM-based vulnerabilities.
# Install chromium dependency
nuclei -install-path-helper # shows headless setup instructions
# Run headless templates
nuclei -u https://target.example.com -headless -t headless/
# Specific headless templates
nuclei -u https://target.example.com -t headless/generic/open-redirect.yaml
# Headless with browser flags
nuclei -u https://target.example.com -headless \
-page-timeout 30 \
-browser-args "no-sandbox,disable-gpu"
Interactsh — OOB Testing
Nuclei integrates with interactsh for out-of-band vulnerability detection (SSRF, blind XXE, OOB SQLi, etc.)
# Public interactsh server (default, requires outbound DNS/HTTP)
nuclei -l targets.txt -t fuzzing/ssrf.yaml # uses oast.pro by default
# Self-hosted interactsh server
interactsh-client -server interactsh.example.com -token mytoken &
nuclei -l targets.txt -iserver interactsh.example.com -itoken mytoken
# Disable interactsh (for air-gapped or strict environments)
nuclei -l targets.txt -no-interactsh
Template Using interactsh
id: blind-ssrf-example
info:
name: Blind SSRF via interactsh
severity: high
tags: ssrf,oob
http:
- method: GET
path:
- "{{BaseURL}}/fetch?url=http://{{interactsh-url}}"
matchers:
- type: word
part: interactsh_protocol
words:
- "http"
Writing Custom Templates
HTTP Template (GET with regex)
id: exposed-git-config
info:
name: Exposed .git/config
severity: medium
tags: git,exposure,config
http:
- method: GET
path:
- "{{BaseURL}}/.git/config"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
words:
- "[core]"
part: body
extractors:
- type: regex
regex:
- "url = (.*)"
part: body
HTTP Template (POST with dynamic extraction)
id: graphql-introspection
info:
name: GraphQL Introspection Enabled
severity: low
tags: graphql,exposure
http:
- method: POST
path:
- "{{BaseURL}}/graphql"
- "{{BaseURL}}/api/graphql"
headers:
Content-Type: application/json
body: '{"query":"{__schema{types{name}}}"}'
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
words:
- "__schema"
part: body
Workflows
Workflows chain templates — run subsequent templates only if previous ones match.
id: wordpress-workflow
info:
name: WordPress Detection and Vuln Scan
severity: info
tags: wordpress,workflow
workflows:
- template: technologies/wordpress-detect.yaml
subtemplates:
- template: cves/2020/CVE-2020-11738.yaml
- template: vulnerabilities/wordpress/
nuclei -l targets.txt -w workflows/wordpress-workflow.yaml
The Full Recon Pipeline
subfinder → httpx → nuclei
# 1. Enumerate subdomains
subfinder -d example.com -silent -o subdomains.txt
# 2. Probe live web services
cat subdomains.txt | httpx -silent -o live_hosts.txt
# With port expansion:
cat subdomains.txt | httpx -silent -ports 80,443,8080,8443,8888 -o live_hosts.txt
# 3. Nuclei scan on live hosts
nuclei -l live_hosts.txt -t cves/ -t exposures/ \
-severity critical,high \
-rl 100 -c 25 \
-json -o findings.jsonl
# One-liner (streaming)
subfinder -d example.com -silent | \
httpx -silent | \
nuclei -t cves/ -severity critical,high -json -o critical_findings.jsonl
Advanced Techniques
Template Filtering with Config File
# ~/.config/nuclei/config.yaml
severity:
- critical
- high
exclude-tags:
- dos
- intrusive
- fuzz
rate-limit: 150
concurrency: 30
nuclei -l targets.txt -config ~/.config/nuclei/config.yaml
# Resume interrupted scan
nuclei -l targets.txt -t cves/ -resume /path/to/resume.cfg
# Custom auth headers
nuclei -u https://target.example.com -H "Authorization: Bearer eyJ..." -t exposures/
# Proxy through Burp Suite
nuclei -l targets.txt -proxy http://127.0.0.1:8080 -ni
Integration with Other Tools
# Results into Elasticsearch
nuclei -l targets.txt -json | \
jq -c '. + {"@timestamp": now | todate}' | \
curl -X POST "http://elk:9200/nuclei/_doc" -H 'Content-Type: application/json' -d @-
# Slack notification for critical findings
nuclei -l targets.txt -severity critical -json | \
jq -r '"CVE Found: \(.info.name) on \(.host) [\(.severity)]"' | \
xargs -I{} curl -X POST -H 'Content-type: application/json' \
--data '{"text":"{}"}' https://hooks.slack.com/services/YOUR/WEBHOOK/URL
# GitHub Actions CI — SARIF upload
nuclei -l targets.txt -severity high,critical -sarif-export nuclei.sarif
Troubleshooting
| Issue | Fix |
|---|---|
| No results despite known vulns | Run with -v -debug to inspect requests/responses |
| Rate limit errors (429) | Lower -rl (e.g. -rl 20) and -c 5 |
| Templates not found | Run nuclei -ut to update template library |
| SSL errors on self-signed certs | Add -ni (disable TLS verification) |
| Interactsh OOB not triggering | Check outbound DNS/HTTP; use -iserver self-hosted |
| Too many false positives | Add -exclude-tags intrusive,fuzz and -severity high,critical |
| Headless not working | Install chromium: apt install chromium or chromium-browser |
| Memory usage too high | Reduce -c and -bs; split target list |
Built by Red Hound InfoSec — On-demand offensive security expertise for SMBs. 20+ years of Fortune 500 experience. Penetration testing, attack surface analysis, and security consulting.
Related reading: Why Your Penetration Test Report Is Useless (And What to Ask For Instead)
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most automation workflows skills give in ~3.6k tokens
Counted across 745 of the 1,008 authors here whose files we hold, read 2026-08-07
- Write conventional commit messagesin 36 of 745, across 35 files
- Delete branches after mergein 30 of 745, across 21 files
- Make atomic commitsin 25 of 745, across 15 files
- Write minimal code to pass testsin 22 of 745, across 10 files
- Re-snapshot after navigation or DOM changesin 21 of 745, across 13 files
- Use try-catch for error handlingin 20 of 745, across 8 files
- Run tests before committingin 20 of 745, across 12 files
- Write tests before implementationin 20 of 745, across 8 files
- Configure branch protection rulesin 19 of 745, across 5 files
- Explain the why in commit messagesin 19 of 745, across 9 files
- Refactor code while tests remain greenin 19 of 745, across 6 files
- Interact with elements using refsin 19 of 745, across 11 files
Said here and by no other author read
- write custom detection templates in YAML
- select templates by tags and severity
- update templates to the latest community versions
- tune scan performance with rate limiting and concurrency
- use interactsh for out-of-band vulnerability detection
- execute headless scans for DOM-based vulnerabilities
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.