Skip to content

Conversation

@dogancanbakir
Copy link
Member

@dogancanbakir dogancanbakir commented Nov 11, 2025

Proposed changes

closes #5823

Checklist

  • Pull request is created against the dev branch
  • All checks passed (lint, unit/integration/regression tests etc.) with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Summary by CodeRabbit

Release Notes

  • New Features

    • Added --max-time (or -mt) CLI flag to control maximum execution duration for scans. When the time limit is reached, scans gracefully terminate and complete their operations. Supports flexible duration formats (e.g., 1h, 30m, 1h30m).
  • Documentation

    • Updated README with complete documentation for the new maximum execution time flag, including usage examples and best practices.

@auto-assign auto-assign bot requested a review from Mzack9999 November 11, 2025 07:32
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 11, 2025

Walkthrough

Implements a maximum execution time feature by adding a new CLI flag -mt/-max-time, propagating timeout-bounded contexts through execution paths (runner, SDK, multi-scan modes), and introducing context management utilities to support graceful timeout handling.

Changes

Cohort / File(s) Summary
Documentation & CLI
README.md, cmd/nuclei/main.go
Added documentation for new -mt/-max-time CLI flag and bound the flag to options.MaxTime with default value 0
Type System Extensions
pkg/types/types.go, pkg/types/context.go
Added MaxTime field to Options struct and introduced ApplyMaxTimeContext() utility function to create timeout-bound contexts with cancellation and logging on expiry
Automatic Scan Service
pkg/protocols/common/automaticscan/automaticscan.go
Added context-aware constructor NewWithContext(), storing context and cancel function in Service; updated Execute() and execution paths to use the bounded context; refactored New() to delegate to NewWithContext()
Core Execution Paths
internal/runner/runner.go, internal/server/nuclei_sdk.go, lib/multi.go, lib/sdk.go
Applied ApplyMaxTimeContext() at entry points; substituted automatic scan instantiation and template execution calls to use timeout-bound contexts and defer cancellation cleanup

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as CLI Entry
    participant Runner
    participant TimeoutCtx as Timeout Context
    participant ScanService
    participant Engine
    
    User->>CLI: Start nuclei with -mt 1h
    CLI->>Runner: Execute with Options.MaxTime set
    Runner->>TimeoutCtx: ApplyMaxTimeContext(ctx, opts)
    alt MaxTime > 0 and no existing deadline
        TimeoutCtx-->>Runner: (new_ctx, cancel_func, true)
        Note over TimeoutCtx: Context with timeout<br/>configured
    else
        TimeoutCtx-->>Runner: (original_ctx, nil, false)
    end
    Runner->>ScanService: NewWithContext(opts, timeout_ctx)
    ScanService->>ScanService: Store ctx, cancel func
    Runner->>Engine: ExecuteScanWithOpts(timeout_ctx)
    
    par Normal Completion
        Engine->>Engine: Execute scan
        Engine-->>Runner: Scan complete
        Runner->>ScanService: Close() → cancel()
    and Timeout Reached
        TimeoutCtx->>Engine: timeout triggers context.Done()
        Engine-->>Runner: ctx.Err() = context.DeadlineExceeded
        Note over TimeoutCtx: Log timeout<br/>Graceful stop
        Runner->>ScanService: Close() → cancel()
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Context management logic in pkg/types/context.go: Review the timeout application logic, deadline checking, and goroutine spawning for logging—ensure proper cleanup and no goroutine leaks.
  • Automatic scan service refactoring (pkg/protocols/common/automaticscan/automaticscan.go): Pay close attention to the new NewWithContext() constructor, context storage, and cancellation in Close(); verify the delegation in the original New() method works correctly.
  • Cross-entry-point consistency: Verify that all four execution paths (runner, SDK, multi, SDK callback) apply and propagate the max-time context uniformly.
  • Cancel function handling: Ensure deferred cleanup of cancel functions occurs in all code paths to prevent context leaks.

Poem

⏰ A timeout so fair, a max-time so grand,
Graceful it stops when the clock takes its stand,
No more the hanging that plagued us before,
Contexts now bounded, results at the door! 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR implements the first requirement from #5823 (maxtime option for soft kill with graceful stopping) but does not address the second requirement (jsonl streaming to disk). Implement the -jsonl behavior change to write findings directly to disk in JSON Lines format instead of keeping them in memory, as specified in #5823.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: adding a maxtime option to limit overall execution time, which is the main focus of the changeset.
Out of Scope Changes check ✅ Passed All changes directly support the maxtime feature implementation: CLI flag binding, context-aware timeout application, and supporting utility functions. No unrelated changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 5823_add_maxtime_option

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
pkg/types/context.go (1)

12-30: Consider goroutine lifecycle.

The goroutine spawned on lines 22-27 will remain blocked on execCtx.Done() until the timeout expires or the context is cancelled. This is generally acceptable for a logging goroutine, but be aware that:

  1. If the scan completes before the timeout, the goroutine will continue running until timeout or cancellation
  2. The goroutine holds a reference to execCtx and logger, preventing GC until it completes

This is a common pattern for timeout logging and should be fine for the use case, but consider documenting this behavior.

internal/runner/runner.go (1)

796-807: Verify if redundant max-time context application is intentional.

The max-time context is applied here at the runner level (lines 797), but automaticscan.NewWithContext also applies it internally. While safe due to the hasDeadline guard in ApplyMaxTimeContext, this redundancy creates ambiguity about ownership and could confuse future maintainers.

Consider clarifying the design:

  • Option 1 (recommended): Apply max-time context only at the runner level and remove the internal application from automaticscan.NewWithContext
  • Option 2: Remove the application here and let automaticscan.NewWithContext handle it exclusively

Option 1 is preferred for centralized control and consistency with executeTemplatesInput (which must apply the context since ExecuteScanWithOpts doesn't).

Based on relevant code snippets from pkg/protocols/common/automaticscan/automaticscan.go.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cc0f1e9 and 7f51789.

📒 Files selected for processing (9)
  • README.md (1 hunks)
  • cmd/nuclei/main.go (1 hunks)
  • internal/runner/runner.go (2 hunks)
  • internal/server/nuclei_sdk.go (1 hunks)
  • lib/multi.go (1 hunks)
  • lib/sdk.go (1 hunks)
  • pkg/protocols/common/automaticscan/automaticscan.go (5 hunks)
  • pkg/types/context.go (1 hunks)
  • pkg/types/types.go (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Format Go code using go fmt
Run static analysis with go vet

Files:

  • pkg/types/types.go
  • lib/multi.go
  • internal/server/nuclei_sdk.go
  • lib/sdk.go
  • cmd/nuclei/main.go
  • pkg/types/context.go
  • pkg/protocols/common/automaticscan/automaticscan.go
  • internal/runner/runner.go
pkg/protocols/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Each protocol implementation must provide a Request interface with methods Compile(), ExecuteWithResults(), Match(), and Extract()

Files:

  • pkg/protocols/common/automaticscan/automaticscan.go
🧬 Code graph analysis (6)
lib/multi.go (1)
pkg/types/context.go (1)
  • ApplyMaxTimeContext (12-30)
internal/server/nuclei_sdk.go (2)
pkg/types/context.go (1)
  • ApplyMaxTimeContext (12-30)
pkg/types/types.go (1)
  • Options (34-474)
lib/sdk.go (1)
pkg/types/context.go (1)
  • ApplyMaxTimeContext (12-30)
pkg/types/context.go (2)
pkg/protocols/common/contextargs/contextargs.go (1)
  • Context (22-33)
pkg/types/types.go (1)
  • Options (34-474)
pkg/protocols/common/automaticscan/automaticscan.go (4)
pkg/protocols/common/contextargs/contextargs.go (2)
  • Context (22-33)
  • New (36-38)
pkg/types/types.go (1)
  • Options (34-474)
pkg/types/context.go (1)
  • ApplyMaxTimeContext (12-30)
pkg/input/provider/simple.go (1)
  • NewSimpleInputProviderWithUrls (22-28)
internal/runner/runner.go (3)
pkg/types/context.go (1)
  • ApplyMaxTimeContext (12-30)
pkg/protocols/common/automaticscan/automaticscan.go (2)
  • NewWithContext (78-137)
  • Options (47-52)
pkg/types/types.go (1)
  • Options (34-474)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lint
🔇 Additional comments (13)
README.md (1)

302-302: LGTM!

The documentation clearly describes the new max-time option with an appropriate example.

pkg/types/types.go (2)

316-317: LGTM!

The MaxTime field addition is straightforward and properly documented.


615-615: LGTM!

The Copy method correctly propagates the MaxTime field to the new instance.

internal/server/nuclei_sdk.go (1)

184-192: Verify context source.

The code creates a fresh context.Background() each time. Consider if there's an existing context (e.g., from the HTTP request or the nucleiExecutor struct) that should be used instead to propagate cancellation signals from upstream callers.

cmd/nuclei/main.go (1)

433-433: LGTM!

The CLI flag is correctly defined with appropriate names, type, default value, and description. The example in the description helps users understand the expected format.

lib/multi.go (1)

168-173: LGTM!

The max-time context is correctly applied and the derived context is used for scan execution. The cancel function is properly deferred for cleanup.

lib/sdk.go (1)

268-284: LGTM!

The max-time context is correctly applied and consistently used throughout the method. The completion/timeout handling in the select statement properly uses execCtx.Done() and execCtx.Err().

pkg/protocols/common/automaticscan/automaticscan.go (4)

73-85: LGTM!

The context-aware constructor is well-implemented:

  • Properly defaults to context.Background() if nil
  • Applies max-time context when options are available
  • Stores the cancel function for lifecycle management

141-143: LGTM!

The Close method correctly invokes the cancel function for proper context cleanup.


156-160: LGTM!

The context cancellation check enables graceful early termination when the max-time is reached.


217-217: LGTM!

Using s.ctx instead of context.Background() correctly propagates the max-time context through the execution path.

internal/runner/runner.go (2)

843-849: Correct implementation of max-time context for template execution.

The context handling pattern is properly implemented:

  • Context is created and bounded with max-time
  • Cancel function is deferred with nil check to prevent panic
  • Context is correctly passed to ExecuteScanWithOpts

This is necessary at the runner level since the engine doesn't apply max-time internally.


796-807: Consider adding tests and documentation for max-time feature.

The PR checklist indicates that tests and documentation haven't been added yet. Given that this is a new user-facing feature (-mt/--max-time flag), please ensure:

  1. Tests: Add unit tests covering:

    • Context timeout triggers graceful shutdown
    • Cancel function is properly called
    • Behavior when MaxTime <= 0 (feature disabled)
    • Behavior when context already has a deadline
  2. Documentation: Update relevant docs to explain:

    • The -mt/--max-time flag usage and format
    • Expected behavior when timeout is reached
    • Impact on scan results (graceful stop vs hard kill)

Per PR objectives and coding guidelines.

Also applies to: 843-849

@dogancanbakir dogancanbakir self-assigned this Nov 11, 2025
Copy link
Member

@Mzack9999 Mzack9999 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the functionality can be already obtained by using nuclei as SDK and providing a context with max deadline execution for example. What do you think?

@dogancanbakir
Copy link
Member Author

dogancanbakir commented Nov 23, 2025

I think the functionality can be already obtained by using nuclei as SDK and providing a context with max deadline execution for example. What do you think?

@Mzack9999, however, this is aimed explicitly at CLI users, as it won't be possible for them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] -maxtime maximum testing time per host (soft kill) and -jsonl writes directly to disk

3 participants