Skip to content

Add context cancellation support to all enumeration sources #1679

@knakul853

Description

@knakul853

Current Behavior

Sources do not properly respect context cancellation, causing enumeration to continue even after the context is cancelled.

Problem:

  • Pagination loops and result processing loops do not check ctx.Done()
  • Sources continue making HTTP requests and sending results after cancellation
  • Callers cannot abort enumeration early

Changes Proposed:

  • Add context checks in pagination/polling loops for sources with cursors
  • Use select with ctx.Done() when sending results into channels
  • Update passive.go to check context before forwarding results

Subfinder version

v2.10.1

Steps To Reproduce

Run a discovery and try to cancel the request by cancelling the context. Subfinder continues enumeration despite the cancelled context.

Example:

package main

import (
    "context"
    "fmt"
    "io"
    "time"

    "github.com/projectdiscovery/subfinder/v2/pkg/resolve"
    "github.com/projectdiscovery/subfinder/v2/pkg/runner"
)

func main() {
    opts := &runner.Options{
        Threads:            10,
        Timeout:            60,
        MaxEnumerationTime: 30,
    }

    foundCh := make(chan struct{}, 1)
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    opts.ResultCallback = func(result *resolve.HostEntry) {
        fmt.Printf("Found: %s\n", result.Host)
        select {
        case foundCh <- struct{}{}:
            cancel() // Cancel context after first result
        default:
        }
    }

    subfinder, err := runner.NewRunner(opts)
    if err != nil {
        panic(err)
    }

    start := time.Now()
    doneCh := make(chan struct{})
    go func() {
        defer close(doneCh)
        _, _ = subfinder.EnumerateSingleDomainWithCtx(ctx, "facebook.com", []io.Writer{io.Discard})
    }()

    select {
    case <-foundCh:
        fmt.Println("First subdomain found, context cancelled")
    case <-doneCh:
        fmt.Println("Enumeration completed")
    }

    <-doneCh
    fmt.Printf("Total time: %v\n", time.Since(start))
    // Expected: exit immediately after first result
    // Actual: continues until timeout (~60s)
}

Expected Behavior

Enumeration should stop immediately (within milliseconds) after context cancellation. Subfinder should respect the caller’s context.

Subfinder version (again for template compatibility)

v2.10.1

Current Behavior (template)

Context cancellation is not respected during enumeration.

Expected Behavior (template)

Enumeration should stop as soon as the context is cancelled.

Steps To Reproduce (template)

  1. Run subfinder enumeration using a context
  2. Cancel the context after first result
  3. Enumeration continues until timeout instead of stopping

Metadata

Metadata

Assignees

Labels

Type: BugInconsistencies or issues which will cause an issue or problem for users or implementors.

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions