Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7f6096e
fix(hosterrorscache): skip hosts that consistently time out (#7455)
knakul853 Jun 13, 2026
acff3e3
chore(deps): bump the modules group with 3 updates (#7463)
dependabot[bot] Jun 15, 2026
63124ef
per-host http client pool (#7301)
Mzack9999 Jun 16, 2026
0d78558
fix: preserve explicit target port in network templates (fixes #7323)…
XananasX7 Jun 16, 2026
c0b1f4b
chore(deps): bump govaluate to fix slice-bounds panic on invalid UTF-…
XananasX7 Jun 17, 2026
c041bf2
Fix connection reuse + port pre-flight (#6715)
Mzack9999 Jun 19, 2026
1c440e7
check code template signature before dast load (#7472)
dogancanbakir Jun 19, 2026
9611926
gate mysql allowAllFiles behind -lfa (#7473)
dogancanbakir Jun 19, 2026
85abc4f
bump version
dogancanbakir Jun 19, 2026
1fe6025
bump goja (#7467)
Mzack9999 Jun 20, 2026
4cabca0
chore(deps): strip dependencies (#7457)
dwisiswant0 Jun 20, 2026
0547616
fix: escape literal `.` in ASCII-section regex (#7476)
snicket2100 Jun 21, 2026
a86c4fa
fix(network): record decoded bytes for debug dump (#7478)
snicket2100 Jun 21, 2026
69c8d02
chore(deps): bump actions/checkout from 6 to 7 in the workflows group…
dependabot[bot] Jun 22, 2026
323df47
chore(deps): bump the modules group with 3 updates (#7490)
dependabot[bot] Jun 22, 2026
68daef4
fix(js): escape dbname in lib/pq URL (#7479)
dwisiswant0 Jun 22, 2026
638be44
refactor(templates): centralize opt-in capability gates (#7489)
dwisiswant0 Jun 23, 2026
9def9af
fix(js): respect network policy before dialing ldap (#7494)
dwisiswant0 Jun 23, 2026
7ed3c9e
fix(js): normalize & reject trace file DSN opts in oracle (#7480)
dwisiswant0 Jun 23, 2026
4c03c29
fix(js): escape mssql database name in conn URL (#7481)
dwisiswant0 Jun 23, 2026
3a8b65c
fix(js): reject unsandboxed ccache writes in krbforge (#7482)
dwisiswant0 Jun 23, 2026
8a02819
fuzz: add parser harnesses for raw requests & templates (#7459)
dwisiswant0 Jun 23, 2026
14b89f8
fix(http): reject request-condition(s) in fuzzing (#7466)
dwisiswant0 Jun 23, 2026
1512979
chore(deps): drop yaml.v2 from fuzz harness
dwisiswant0 Jun 23, 2026
2d84075
fix(yaml): reject recursive include chains (#7492)
dwisiswant0 Jun 24, 2026
4dc5c3e
fix(engine): resolve memory and goroutine leaks in embedded engine us…
ThryLox Jun 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/compat-checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go/compat-checks@v1
with:
go-version: "stable"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/flamegraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
TARGET_URL: "http://honey.scanme.sh/-/?foo=bar"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/nuclei-action/cache@v3
- run: make build
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/fuzz.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
outputs:
matrix: ${{ steps.discover.outputs.matrix }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
with:
go-version-file: go.tool.mod
Expand All @@ -37,7 +37,7 @@ jobs:
GOFUZZ_PACKAGE: ${{ matrix.pkg }}
FUZZ_DURATION: 15m
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
with:
go-version-file: go.tool.mod
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/generate-docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
if: ${{ !endsWith(github.actor, '[bot]') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/actions/setup/git@v1
- run: make syntax-docs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/generate-pgo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
TARGET_LIST: "/tmp/targets.txt"
PROFILE_MEM: "/tmp/nuclei-profile"
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/nuclei-action/cache@v3
- run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/govulncheck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
env:
OUTPUT: "/tmp/results.sarif"
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
with:
go-version-file: go.tool.mod
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/memogen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
if: ${{ github.repository == 'projectdiscovery/nuclei' && !endsWith(github.actor, '[bot]') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/actions/setup/git@v1
- run: make memogen
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/perf-regression.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
env:
BENCH_OUT: "/tmp/bench.out"
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/nuclei-action/cache@v3
- run: make build-test
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
needs: ["pgo"]
runs-on: ubuntu-latest-16-cores
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/download-artifact@v8
Expand Down
73 changes: 63 additions & 10 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ jobs:
if: ${{ !endsWith(github.actor, '[bot]') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/nuclei-action/cache@v3
- uses: projectdiscovery/actions/golangci-lint/v2@v1
# go vet runs once here (not per-OS in the tests matrix): it is platform
# independent and folding it into the lint gate fails fast on a cheap
# runner before the heavy test/integration jobs start.
- run: make vet

tests:
name: "Tests"
Expand All @@ -37,7 +42,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macOS-latest]
runs-on: "${{ matrix.os }}"
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/nuclei-action/cache@v3
- uses: projectdiscovery/actions/free-disk-space@v1
Expand All @@ -49,14 +54,34 @@ jobs:
misc-packages: 'false'
docker-images: 'false'
tools-cache: 'false'
- run: make vet
- run: make build
- run: make test
# The data-race detector is OS-independent, so we only pay its ~2-3x cost
# on ubuntu; windows/macOS run the same suite without instrumentation.
- name: "Unit tests (race)"
run: make test
if: ${{ matrix.os == 'ubuntu-latest' }}
env:
PDCP_API_KEY: "${{ secrets.PDCP_API_KEY }}"
- name: "Unit tests"
run: make test RACE=
if: ${{ matrix.os != 'ubuntu-latest' }}
env:
PDCP_API_KEY: "${{ secrets.PDCP_API_KEY }}"
- run: go run -race . -l ${{ github.workspace }}/internal/tests/functional/testdata/targets.txt -id tech-detect,tls-version
if: ${{ matrix.os != 'windows-latest' }} # known issue: https://github.com/golang/go/issues/46099
working-directory: cmd/nuclei/
# Hermetic HTTP-engine scale regression: stands up many loopback hosts and
# asserts finding parity across a diverse template set (per-host pool,
# connection-reuse and http->https tracker + cookie-reuse). Race
# build runs on ubuntu only (same rationale as the unit tests above);
# other OSes run it plain. Large runs stay opt-in locally via
# NUCLEI_SCALE_HOSTS.
- name: "Scale regression (race)"
run: go test -tags=regression -race -timeout 15m ./lib/tests -run TestScaleRegression
if: ${{ matrix.os == 'ubuntu-latest' }}
- name: "Scale regression"
run: make regression
if: ${{ matrix.os != 'ubuntu-latest' }}

sdk:
name: "Run example SDK"
Expand All @@ -65,7 +90,7 @@ jobs:
env:
GITHUB_TOKEN: "${{ github.token }}"
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/nuclei-action/cache@v3
- name: "Simple"
Expand All @@ -90,9 +115,10 @@ jobs:
os: [ubuntu-latest, windows-latest, macOS-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/python@v1
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/nuclei-action/cache@v3
- run: make integration
env:
PDCP_API_KEY: "${{ secrets.PDCP_API_KEY }}"
Expand All @@ -109,9 +135,10 @@ jobs:
os: [ubuntu-latest, windows-latest, macOS-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/python@v1
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/nuclei-action/cache@v3
- uses: projectdiscovery/nuclei-action@v3
with:
version: latest
Expand All @@ -125,7 +152,7 @@ jobs:
env:
GITHUB_TOKEN: "${{ github.token }}"
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
- uses: projectdiscovery/nuclei-action/cache@v3
- run: make template-validate
Expand All @@ -139,19 +166,45 @@ jobs:
contents: read
security-events: write
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: github/codeql-action/init@v4
with:
languages: 'go'
- uses: github/codeql-action/autobuild@v4
- uses: github/codeql-action/analyze@v4
with:
output: sarif-results
upload: never
category: "/language:go"
# internal/fuzzplayground is a deliberately vulnerable mock server used to
# exercise nuclei's fuzzing templates (CMDI/SQLi/SSRF/etc. are by design),
# so its CodeQL alerts are expected false positives. paths-ignore has no
# effect for compiled languages, so drop those results from the SARIF
# before upload instead.
- name: "Filter fuzzplayground alerts from SARIF"
run: |
for sarif in sarif-results/*.sarif; do
[ -e "$sarif" ] || continue
jq '
.runs[].results |= map(
select(
[ .locations[]?.physicalLocation.artifactLocation.uri // "" ]
| any(startswith("internal/fuzzplayground/")) | not
)
)
' "$sarif" > "$sarif.filtered" && mv "$sarif.filtered" "$sarif"
done
- uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: sarif-results
category: "/language:go"

release:
name: "Release test"
needs: ["tests"]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: projectdiscovery/actions/setup/go@v1
with:
go-version: "stable"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/typos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ jobs:
if: ${{ !endsWith(github.actor, '[bot]') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: crate-ci/typos@v1.47.2
14 changes: 12 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ endif

.PHONY: all build build-stats clean devtools-all devtools-bindgen devtools-scrapefuncs fuzz fuzz-ci fuzz-tools
.PHONY: devtools-tsgen docs docgen dsl-docs functional go-build lint lint-strict fuzzplayground syntax-docs
.PHONY: integration integration-debug jsupdate-all jsupdate-bindgen jsupdate-tsgen memogen scan-charts test test-with-lint
.PHONY: integration integration-debug regression jsupdate-all jsupdate-bindgen jsupdate-tsgen memogen scan-charts test test-with-lint
.PHONY: tidy ts verify download vet template-validate build-fuzz discover-fuzz-packages

all: build
Expand Down Expand Up @@ -82,7 +82,11 @@ syntax-docs: docgen
syntax-docs:
./bin/docgen SYNTAX-REFERENCE.md nuclei-jsonschema.json

test: GOFLAGS = -race -v -timeout 1h -count 1
# RACE controls the data-race detector (on by default for local runs). CI builds
# the race variant on a single OS and passes RACE= elsewhere, since data races are
# OS-independent and the detector costs ~2-3x build+run time on every runner.
RACE ?= -race
test: GOFLAGS = $(RACE) -v -timeout 1h -count 1
test:
$(GOTEST) $(GOFLAGS) ./...

Expand All @@ -92,6 +96,12 @@ integration:
integration-debug:
$(GOTEST) -tags=integration ./internal/tests/integration -v $(GO_TEST_ARGS) -args $(INTEGRATION_ARGS)

# Opt-in HTTP engine scale regression harness (not part of CI). Stands up many
# loopback hosts and asserts finding parity across a diverse template set.
# Override host count with NUCLEI_SCALE_HOSTS, e.g. NUCLEI_SCALE_HOSTS=500 make regression
regression:
$(GOTEST) -tags=regression -timeout 30m ./lib/tests -run TestScaleRegression -v

functional: build
@release_binary="$$(command -v nuclei.exe 2>/dev/null || command -v nuclei 2>/dev/null)"; \
if [ -z "$$release_binary" ]; then \
Expand Down
4 changes: 3 additions & 1 deletion cmd/nuclei/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ import (

"github.com/projectdiscovery/gologger"
_pdcp "github.com/projectdiscovery/nuclei/v3/internal/pdcp"
"github.com/projectdiscovery/nuclei/v3/pkg/utils/yaml"
"github.com/projectdiscovery/utils/auth/pdcp"
"github.com/projectdiscovery/utils/env"
_ "github.com/projectdiscovery/utils/pprof"
stringsutil "github.com/projectdiscovery/utils/strings"
"github.com/rs/xid"
"gopkg.in/yaml.v2"

"github.com/projectdiscovery/goflags"
"github.com/projectdiscovery/gologger/levels"
Expand Down Expand Up @@ -418,6 +418,7 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.CreateGroup("rate-limit", "Rate-Limit",
flagSet.IntVarP(&options.RateLimit, "rate-limit", "rl", 150, "maximum number of requests to send per second"),
flagSet.DurationVarP(&options.RateLimitDuration, "rate-limit-duration", "rld", time.Second, "maximum number of requests to send per second"),
flagSet.BoolVar(&options.PerHostRateLimit, "per-host-rate-limit", false, "enable per-host rate limiting (global rate limit becomes unlimited when enabled)"),
flagSet.IntVarP(&options.RateLimitMinute, "rate-limit-minute", "rlm", 0, "maximum number of requests to send per minute (DEPRECATED)"),
flagSet.IntVarP(&options.BulkSize, "bulk-size", "bs", 25, "maximum number of hosts to be analyzed in parallel per template"),
flagSet.IntVarP(&options.TemplateThreads, "concurrency", "c", 25, "maximum number of templates to be executed in parallel"),
Expand Down Expand Up @@ -446,6 +447,7 @@ on extensive configurability, massive extensibility and ease of use.`)
}),
flagSet.DurationVarP(&options.InputReadTimeout, "input-read-timeout", "irt", time.Duration(3*time.Minute), "timeout on input read"),
flagSet.BoolVarP(&options.DisableHTTPProbe, "no-httpx", "nh", false, "disable httpx probing for non-url input"),
flagSet.BoolVar(&options.PreflightPortScan, "preflight-portscan", false, "run preflight resolve + TCP portscan and filter targets before scanning (disabled by default)"),
flagSet.BoolVar(&options.DisableStdin, "no-stdin", false, "disable stdin processing"),
)

Expand Down
Loading