* feat(filepath): add IsPathWithinAnyDirectory func
Signed-off-by: Dwi Siswanto <git@dw1.io>
* refactor: use path-aware filesystem containment checks
Several filesystem trust boundaries relied on
lexical prefix checks to decide whether a path
fell under an allowed directory. That let sibling
paths be treated as if they were children of
trusted directories.
Replace those checks with canonical path
containment checks for helper payload loading,
template archive extraction, custom template
metadata, template path classification, and
headless screenshot output validation.
Signed-off-by: Dwi Siswanto <git@dw1.io>
* adding more tests
* fixing tests
* adding test
---------
Signed-off-by: Dwi Siswanto <git@dw1.io>
Co-authored-by: Mzack9999 <mzack9999@protonmail.com>
`ConnectSMBInfoMode` only tried SMBv1 when SMB2/3
negotiation failed so dual-stack servers could
report `SupportV1` as false even when SMBv1 was
enabled.
Run a same-target SMBv1 probe after successful
SMB2/3 negotiation and merge the support flag into
the returned log w/o changing the negotiated
SMB2/3 version.
Fixes#4832
Signed-off-by: Dwi Siswanto <git@dw1.io>
- Add TestParseNTLMResponse_Minimal48Bytes to explicitly cover the exact
lower boundary of the len<48 guard (minimal valid challenge, no target
name or info)
- Replace the inline immediately-invoked function for the wrong-message-type
case with a pre-built local variable for readability
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ParseNTLMResponse read fixed-header fields at offsets 12-14, 16-20, 40-42,
and 44-48 after only checking len>=12, causing a slice-bounds-out-of-range
panic for any NTLM section between 12 and 47 bytes. Because this input comes
from untrusted network data, a malicious or malformed telnet server could crash
the scanner (or the embedding host process when used via the SDK).
Raise the guard to len<48 so the full fixed header is present before any field
is touched. Add unit tests covering the happy path, existing error cases, and a
no-panic regression table for every truncated length in [12,47].
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevent pooled and non-pooled goja runtimes from
being reused or cleaned up when the `RunProgram`
goroutine fails to exit after context cancellation
and `Interrupt()`. In that state, the goroutine
may still be mutating runtime state, so touching
the runtime/returning it to the pool can cause
fatal concurrent map access panics.
Add an explicit `errRuntimeTerminationTimeout`
path that abandons the runtime, keeps the related
concurrency slot reserved, and releases that slot
only from a reaper after the orphaned goroutine
exits. Preserve `errors.Is` compatibility with the
original context cancellation cause.
Keep normal cleanup behavior unchanged, including
callback panic cleanup, and add regression tests
for stuck-interrupt handling that verify runtime
abandonment and delayed slot release.
Fixes#7376
* fix race condition
* fixing review comments
* fix(js): defer runtime cleanup
When a runtime is abandoned, we must not touch the
goja runtime after `RunProgram` has exceeded the
interrupt grace period. At the same time, cleanup
still needs to run on every normal exit before
returning the runtime to the pool, including setup
callback panics.
Signed-off-by: Dwi Siswanto <git@dw1.io>
---------
Signed-off-by: Dwi Siswanto <git@dw1.io>
Co-authored-by: Dwi Siswanto <git@dw1.io>
Bumps clistats, fastdialer, retryablehttp-go, dsl, networkpolicy,
ratelimit, sarif, utils, wappalyzergo, cdncheck. dsl v0.8.18 moves to
the projectdiscovery/govaluate fork, and utils v0.11.0 pulls aurora v4,
so the corresponding imports and type references are migrated.
Refs #7380.
The QueryAuthStrategy case in raw.Request.ApplyAuthStrategy parses
r.FullURL into a local 'parsed', appends auth params to parsed.Params,
then returns without writing back to r.FullURL. Every other branch in
the same switch mutates r.Headers, and the standalone QueryAuthStrategy
.Apply / .ApplyOnRR in pkg/authprovider/authx/query_auth.go both write
back to req.URL.RawQuery. Only the raw-request branch was missing the
write-back, so raw templates matching a 'query' auth secret silently
drop the auth params.
Adds r.FullURL = parsed.String() after the loop. New unit test fails
on dev and passes with the fix.
client-go v1.x widened ID fields from int to int64 across the API surface
(User.ID, Issue.ID, ListOptions.Page/PerPage). Adjust the tracker to the
new signatures: Integration.userID, the assignee slice, the FormatInt
arguments, and ListOptions casts.
Keep Options.DuplicateIssuePageSize / DuplicateIssueMaxPages as int —
that struct is user-facing YAML and YAML ints round-trip into int64 fine.
Cast at the call site only.
UpdateIssue and CreateIssueNote signatures also widened, but issue.IID
is already int64 in v1.x, so existing call sites compile unchanged.
`FindExpressions` checks marker contents with
govaluate before doing normal placeholder
replacement. That breaks valid hyphenated names
like `request-id`: govaluate reads them as
subtraction lol, and the lookup fails with a
missing request parameter.
If a marker exactly matches a key in the
replacement map, treat it as a plain placeholder
and let normal replacement handle it. Authored
expressions should still be evaluated, and
malformed helper calls should still return errors.
Fixes#7395
Signed-off-by: Dwi Siswanto <git@dw1.io>
Add shared auth, options, result, redaction, and
adapter support for GoExec-backed JavaScript
helpers, including:
* `nuclei/wmi`
* `nuclei/tsch`
* `nuclei/scmr`
* `nuclei/dcom`
through generated bindings, and register them with
the JS compiler.
Also make JS generators to skip internal helper
packages and test files.
Signed-off-by: Dwi Siswanto <git@dw1.io>
Workflow inputs get updated with extracted values,
but later executors don't refresh their template
contexts from that state. Child subtemplates reuse
the same input object, letting sibling state leak
across concurrent executions. HTTP race requests
also ignore dynamic values when building requests.
Fix this by syncing the current workflow input
into each executor's template context, cloning
inputs passed to subtemplates, and forwarding
dynamic values to race request generation.
Fixes#5399
Signed-off-by: Dwi Siswanto <git@dw1.io>
propagation, sibling isolation, and same-step
refresh, plus an integration workflow test
covering the race path.
Signed-off-by: Dwi Siswanto <git@dw1.io>
CloseIssue iterated transitions comparing transition.Name against StatusNot.
StatusNot is semantically a status name (same field is used for the JQL
"status != ..." clause in FindExistingIssue), so the transition-name match
broke any workflow whose transitions have distinct verb-style names (common
in customized enterprise workflows). With default Atlassian workflows the
transition name happens to equal the target status name, masking the bug.
Compare against transition.To.Name instead, so the behavior is consistent
with the field's semantics and with how StatusNot is already used in JQL.
* Interrupt goja runtime on context cancel
* undo import formats
* do both actions in same go-routine to prevent any possible race condition
* Convert the watchdog, into a simpeler construction which still guarantees the same promises
* move the recover to the go routine, and return named return since we now can use the channel
* remove unnecessary tests
* add extra safety in case process refuses to get interrupted
* remove unnecessary ExecFuncWithTwoReturns
* remove named return values
* fix(expressions): avoid helper eval in literal checks
`hasLiteralsOnly()` currently evaluates helper
expressions while deciding whether "{{...}}"
contains unresolved variables, which makes
validation paths run side-effectful helpers.
Just replace that runtime eval with a
`Vars()` len check so unresolved-variable
detection literally stays literal (am I writing it
right?), and of course side-effect free.
Also make `Evaluate()` return template-authored
expression compile/eval errors instead of
logging and then keep continuing, so malformed
helper calls still fail in the rendering path.
Fixes#7320
Signed-off-by: Dwi Siswanto <git@dw1.io>
* fix(javascript): avoid nil map panic on arg eval failure
`getArgsCopy()` logs and counts argument
evaluation failures, but continues to store Port
in `argsCopy` even when `evaluateArgs()` returns.
This causes malformed JavaScript args like
"{{base64()}}" to panic instead of returning the
original error.
Return the evaluation error immediately after
reporting it to prevent the panic and make sure
proper error propagation.
Signed-off-by: Dwi Siswanto <git@dw1.io>
---------
Signed-off-by: Dwi Siswanto <git@dw1.io>
* fix(js): respect `allow-local-file-access` in `require`
The goja `require() `function used the default
host filesystem loader which let JavaScript
templates import any local files even when
`allow-local-file-access` was disabled.
Pooled runtimes kept `require()` state around so
a module loaded during a privileged execution
could remain cached for a later restricted one.
Rebuild the require registry per execution after
setting the execution context, and route file-
backed module loads to preserve native modules
while enforcing the same sandbox rules (as
`nuclei/fs`).
Signed-off-by: Dwi Siswanto <git@dw1.io>
* fix: cross-platform sandbox path checks
Replace lexical prefix checks in the template file
sandbox with a shared path containment helper that
canonicalizes both paths before comparing them to
prevent false rejections when the configured
templates directory and the resolved file path
differ only due to symlink expansion on macOS or
path normalization on Windows.
Apply the helper in `protocolstate.NormalizePath()`
and `Options.GetValidAbsPath()` so JS `require()`-
based module loads and helper file resolution use
the same rules.
Signed-off-by: Dwi Siswanto <git@dw1.io>
---------
Signed-off-by: Dwi Siswanto <git@dw1.io>
`interactsh.(*Client).processInteractionForRequest`
was updating the wrapped event under lock but
releasing it before calling `Operators.Execute()`,
allowing async interactsh updates to race with
matcher expr evaluation on the same `InternalEvent`
map, causing fatal concurrent map iteration/write
crashes.
Hold the event lock while populating interactsh
fields and running operators, and use a locked
`eventHash()` helper for matched-template cache
lookups that access the same event data.
Fixes#7319
Signed-off-by: Dwi Siswanto <git@dw1.io>
* fix(js): prevent pool slot starvation under load
Zombie goroutines from timed-out JS executions held pool slots
indefinitely: Add() blocked with context.Background(), and defer Done()
only ran when the goroutine eventually completed. Under load, both
pools (80 pooled + 20 non-pooled slots) filled with zombies, silently
dropping all subsequent matches.
Three changes fix slot lifecycle management:
1. Propagate the 20s deadline context into ExecuteProgram (compiler.go)
so both execution paths can respect the deadline.
2. Replace Add() with AddWithContext(ctx) in both pool.go and
non-pool.go so goroutines waiting for a slot fail fast when the
deadline expires instead of blocking indefinitely.
3. Add a watchdog goroutine that releases the slot when the deadline
expires, even if the zombie is still running. An atomic.Bool
ensures exactly one Done() call between the watchdog and the
normal defer path.
* adding context
* refactor(js): derived the ctx to remaining tractable deadline leaks (#7302)
* refactor(js): use `context.Background` as default instead
Signed-off-by: Dwi Siswanto <git@dw1.io>
* refactor(js): derived the ctx to remaining tractable deadline leaks
Signed-off-by: Dwi Siswanto <git@dw1.io>
* test(js): add `NucleiJS.Context` tests
Signed-off-by: Dwi Siswanto <git@dw1.io>
* fix(cmd): context param exclusion in memoization hash
The memoization template condition for excluding
context parameters from hash keys was incorrect.
The memoize package represents context.Context
types as "&{context Context}" (AST string
representation), not "context.Context".
Signed-off-by: Dwi Siswanto <git@dw1.io>
* chore(js): memogen'ed
Signed-off-by: Dwi Siswanto <git@dw1.io>
---------
Signed-off-by: Dwi Siswanto <git@dw1.io>
* fix(js): hangs in checkRDPEncryption
by bounding socket I/O
Add `setConnDeadlineFromContext` helper to set
deadlines on conns derived from context timeouts.
Move conn cleanup out of loop-scoped defers to
make sure immediate cleanup per probe attempt.
Signed-off-by: Dwi Siswanto <git@dw1.io>
---------
Signed-off-by: Dwi Siswanto <git@dw1.io>
Co-authored-by: Niek den Breeje <AuditeMarlow@users.noreply.github.com>
Co-authored-by: Dwi Siswanto <25837540+dwisiswant0@users.noreply.github.com>
Co-authored-by: Dwi Siswanto <git@dw1.io>