Skip to content

Add per-template Interactsh eviction timeout - #7581

Open
Mzack9999 wants to merge 1 commit into
devfrom
5061-interactsh-eviction
Open

Add per-template Interactsh eviction timeout#7581
Mzack9999 wants to merge 1 commit into
devfrom
5061-interactsh-eviction

Conversation

@Mzack9999

@Mzack9999 Mzack9999 commented Jul 24, 2026

Copy link
Copy Markdown
Member

Summary

  • Add optional interactsh-eviction (seconds) on templates so OAST request cache TTL can be longer for slow callbacks without raising the global -interactions-eviction for every template
  • Wire it through compile → executor options → Interactsh RequestEvent cache expiry; unset keeps the global default

Closes #5061

Summary by CodeRabbit

  • New Features

    • Added an optional per-template interactsh-eviction setting to control how long pending interaction requests are retained.
    • Templates without a custom value continue using the global interaction eviction setting.
    • The setting is supported across HTTP, headless, JavaScript, network, and code-based requests.
    • Non-positive or unset values preserve the default eviction behavior.
  • Bug Fixes

    • Ensured per-template eviction settings are consistently applied to interaction requests and callback tracking.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Changes

Interactsh eviction configuration

Layer / File(s) Summary
Template configuration and duration propagation
pkg/templates/templates.go, pkg/templates/compile.go, pkg/protocols/protocols.go, pkg/templates/interactsh_eviction_test.go, pkg/protocols/interactsh_eviction_test.go
Adds interactsh-eviction, propagates it into executor options, preserves it when copying options, and converts seconds to durations.
Per-request eviction selection
pkg/protocols/common/interactsh/interactsh.go, pkg/protocols/common/interactsh/eviction_test.go
Adds per-request eviction data and applies the override when storing Interactsh request events, with fallback and expiration tests.
Protocol request wiring
pkg/protocols/{code,headless,http,javascript,network}/*
Passes the configured eviction duration through all listed Interactsh request paths.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Template
  participant ProtocolRequest
  participant Interactsh
  participant RequestCache
  Template->>ProtocolRequest: provide InteractshEviction
  ProtocolRequest->>Interactsh: submit RequestData with Eviction duration
  Interactsh->>RequestCache: store request event with selected TTL
Loading

Possibly related PRs

Suggested reviewers: dwisiswant0

Poem

I’m a rabbit with a timer to tune,
Keeping callbacks beneath the moon.
Template by template, the clocks now agree,
Events wait as long as they need to be.
Hop, hop—evictions now flee!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 clearly names the main change: adding a per-template Interactsh eviction timeout.
Linked Issues check ✅ Passed The PR implements the requested per-template interactsh-eviction setting and wires it through templates, executor options, and request eviction handling.
Out of Scope Changes check ✅ Passed The changes stay focused on Interactsh eviction plumbing and tests; no unrelated behavior was introduced.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 5061-interactsh-eviction

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/templates/interactsh_eviction_test.go (1)

10-27: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover compile-time propagation, not only YAML decoding.

This test would still pass if parseTemplateNoVerify stopped copying the value into template.Options. Add an assertion through the real parse/compile path for Template.Options.InteractshEviction or InteractshEvictionDuration().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/templates/interactsh_eviction_test.go` around lines 10 - 27, The test
currently verifies only YAML unmarshalling and must also cover propagation
through the real template parse/compile path. Extend
TestTemplateInteractshEvictionUnmarshal to parse or compile the raw template via
parseTemplateNoVerify, then assert the resulting
Template.Options.InteractshEviction or InteractshEvictionDuration() reflects 300
while retaining the existing unmarshal assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/templates/compile.go`:
- Line 558: Validate Template.InteractshEviction before assigning it to
options.InteractshEviction in the compile flow: reject values less than 0, while
preserving 0 as the unset/default state and allowing positive values. Ensure
invalid configurations return an error instead of reaching EvictionFromSeconds
and being converted to the global TTL.

---

Nitpick comments:
In `@pkg/templates/interactsh_eviction_test.go`:
- Around line 10-27: The test currently verifies only YAML unmarshalling and
must also cover propagation through the real template parse/compile path. Extend
TestTemplateInteractshEvictionUnmarshal to parse or compile the raw template via
parseTemplateNoVerify, then assert the resulting
Template.Options.InteractshEviction or InteractshEvictionDuration() reflects 300
while retaining the existing unmarshal assertion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4a0772e0-fa55-4ac5-8cb1-2f846984c049

📥 Commits

Reviewing files that changed from the base of the PR and between bcf2089 and 8f7c44b.

📒 Files selected for processing (13)
  • pkg/protocols/code/code.go
  • pkg/protocols/common/interactsh/eviction_test.go
  • pkg/protocols/common/interactsh/interactsh.go
  • pkg/protocols/headless/request.go
  • pkg/protocols/http/request.go
  • pkg/protocols/http/request_fuzz.go
  • pkg/protocols/interactsh_eviction_test.go
  • pkg/protocols/javascript/js.go
  • pkg/protocols/network/request.go
  • pkg/protocols/protocols.go
  • pkg/templates/compile.go
  • pkg/templates/interactsh_eviction_test.go
  • pkg/templates/templates.go

Comment thread pkg/templates/compile.go
options.TemplateID = template.ID
options.TemplateInfo = template.Info
options.StopAtFirstMatch = template.StopAtFirstMatch
options.InteractshEviction = template.InteractshEviction

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
fd -a 'compile.go|eviction|InteractshEviction' . | sed 's#^\./##' | head -100
echo

echo "Relevant occurrences:"
rg -n "InteractshEviction|EvictionFromSeconds|minimum=1|parseTemplateNoVerify" . | head -200
echo

echo "compile.go context around 530-575:"
if [ -f pkg/templates/compile.go ]; then
  sed -n '530,575p' pkg/templates/compile.go | nl -ba -v530
fi

Repository: projectdiscovery/nuclei

Length of output: 4297


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "pkg/templates/compile.go relevant snippets:"
awk 'NR>=460 && NR<=568 {printf "%6d\t%s\n", NR, $0}' pkg/templates/compile.go

echo
echo "pkg/templates/templates.go InteractshEviction declarations:"
awk 'NR>=125 && NR<=145 {printf "%6d\t%s\n", NR, $0}' pkg/templates/templates.go

echo
echo "pkg/protocols/protocols.go InteractshEviction declarations/helpers:"
awk 'NR>=100 && NR<=118 {printf "%6d\t%s\n", NR, $0}' pkg/protocols/protocols.go
awk 'NR>=310 && NR<=358 {printf "%6d\t%s\n", NR, $0}' pkg/protocols/protocols.go

echo
echo "pkg/protocols/common/interactsh/interactsh.go EvictionFromSeconds:"
awk 'NR>=380 && NR<=398 {printf "%6d\t%s\n", NR, $0}' pkg/protocols/common/interactsh/interactsh.go

echo
echo "pkg/templates/interactsh_eviction_test.go:"
awk '{printf "%6d\t%s\n", NR, $0}' pkg/templates/interactsh_eviction_test.go

echo
echo "validation search for InteractshEviction:"
rg -n "InteractshEviction|Interactsh.*Eviction|eviction.*minimum|min.*eviction|minimum=1" pkg cmd internal 2>/dev/null | head -200

echo
echo "JSON schema validation setup:"
rg -n "jsonschema|Validate|jsonschema\.|JSONSchema" pkg/protocols pkg/templates pkg/operators 2>/dev/null | head -200

Repository: projectdiscovery/nuclei

Length of output: 50379


🏁 Script executed:

#!/bin/bash
set -EUo pipefail

echo "Template validation call sites:"
awk 'NR>=300 && NR<=350 {printf "%6d\t%s\n", NR, $0}' pkg/templates/templates.go
awk 'NR>=540 && PRIN 580 {printf "%6d\t%s\n", NR, $0}' pkg/templates/templates.go 2>/dev/null || true
rg -n "func .*Validate|tplValidator|Validate|jsonschema" pkg/templates/templates.go pkg/templates/parser.go pkg/templates/*.go 2>/dev/null | head -120

echo
echo "Behavioral probe: YAML unmarshals non-positive eviction fields and InteractshEvictionDuration delegates conversion:"
python3 - <<'PY'
from pathlib import Path
import re

templates_go = Path("pkg/templates/templates.go").read_text()
protocols_go = Path("pkg/protocols/protocols.go").read_text()
compile_go = Path("pkg/templates/compile.go").read_text()
interactsh_go = Path("pkg/protocols/common/interactsh/interactsh.go").read_text()

field = re.search(r'InteractshEviction\s+int`.*`', templates_go).group(0)
jsonschema_tag = re.search(r'jsonschema:"([^"]*)"', field)
print("field_tag:", jsonschema_tag.group(0) if jsonschema_tag else "NO_TAG")
print("field_has_minimum_tag:", "minimum=1" in (jsonschema_tag.group(1) if jsonschema_tag else ""))
print("field_has_validate_tag:", bool(re.search(r'validate:.*[<>!=]', field)))
print("compiles_at_line_558:", "options.InteractshEviction = template.InteractshEviction" in compile_go)
func = re.search(r'func \(e \*ExecutorOptions\) InteractshEvictionDuration\(\).*?return.*?time\.Duration\([^)]*\)\*', protocols_go, re.S).group(0)
print("duration_calls_EvictionFromSeconds:", "InteractshEviction" in func and "interactsh.EvictionFromSeconds(e.InteractshEviction)" in protocols_go)
print("EvictionFromSeconds_negative_returns_zero:", bool(re.search(r'func EvictionFromSeconds\(seconds int\).*?if seconds <= 0 \{\s*return 0\s*\}', interactsh_go, re.S)))

# Inspect applyTemplateVerification body and whether it validates Template.InteractshEviction explicitly.
body = re.search(r'func applyTemplateVerification\(template \*Template, data \[\]byte\).+?\n', "pkg/templates/templates.go", re.S)
print("has_applyTemplateVerification_function:", True)
PY

Repository: projectdiscovery/nuclei

Length of output: 20946


🌐 Web query:

go-playground go yaml unmarshal jsonschema minimum validation required custom tag

💡 Result:

To implement JSON Schema validation for a struct in Go—especially one populated from YAML—you generally need to separate the unmarshaling phase from the validation phase, as the standard go-playground/validator package uses struct tags for validation rather than JSON Schema [1][2][3]. Since Go lacks a native JSON Schema layer, you have three primary approaches to achieve this requirement: 1. Use a Dedicated JSON Schema Library Libraries such as kaptinlin/jsonschema or go-rotini/jsonschema are designed specifically to validate data against a schema [4][5][6]. This is the most robust approach for JSON Schema compliance. - Workflow: First, unmarshal your YAML into a map or struct, then pass it to the library's validation method (e.g., schema.Validate(data)) before proceeding with application logic [4][5][7]. - Some libraries allow you to register default functions or perform "smart unmarshaling" that applies schema defaults [5][6][7]. 2. Use a Custom Validator with go-playground/validator You can implement a custom validation function in the go-playground/validator package that performs JSON Schema checks [2][8]. - Workflow: Register a custom validation tag (e.g., jsonschema) using v.RegisterValidation("jsonschema", customFunc) [2][8]. Inside this function, use a JSON Schema validator library (like gojsonschema) to validate the field's content against your schema [8]. - Note: This adds a dependency and requires manual management of your schema definitions within your Go code [8]. 3. Dedicated YAML Validation Libraries If your requirement is specifically to validate YAML structure and content, libraries like go-yamlvalidator allow you to define schemas (in YAML or JSON) and enforce rules like required fields, type checks, and conditional logic directly on YAML input [9]. Summary of Key Differences: - Structural Tags: The standard validator tags (e.g., validate:"required", validate:"min=10") are highly optimized for direct struct-field validation but do not natively understand complex JSON Schema objects [1][2][10]. - Workflow Separation: To use JSON Schema, you must move away from the "validate-on-unmarshal" pattern and adopt a "unmarshal then validate" pattern [4][7]. This prevents the overhead of validation from blocking the initial data decoding and allows you to use rich JSON Schema features that go-playground/validator does not support [5][7]. Recommendation: For production environments requiring full JSON Schema support, adopt a specialized library like kaptinlin/jsonschema, which handles both validation and schema-aware unmarshaling, keeping your validation logic clean and externalized from struct tags [5][6][7].

Citations:


🌐 Web query:

invopop jsonschema jsonschema validator minimum 1 struct tag validation yaml tag optional

💡 Result:

The invopop/jsonschema library is primarily a JSON Schema generation tool that uses Go struct tags via reflection [1][2]. It does not provide built-in runtime validation of the JSON data against the generated schema; rather, it focuses on generating the schema definition itself from your Go types [2]. Regarding your specific inquiries about struct tag usage: 1. Minimum/Maximum Validation: You can use standard JSON Schema keywords within the jsonschema tag. For example, to set minimum and maximum constraints, use: type Example struct { Value int json:"value" jsonschema:"minimum=1,maximum=10" } [1][3] 2. Optional Fields: In invopop/jsonschema, fields are generally treated as optional if they are omitted from the required list in the generated schema [1][2]. To control this, you can use the standard Go json tag with omitempty: type Example struct { OptionalField string json:"optional_field,omitempty" } [1][3] The library automatically handles the mapping of Go types to JSON Schema. If you need explicit control over nullability, the library includes configurations like NullableFromJSONSchemaTags, which can be enabled to look for a jsonschema:"nullable" tag [4]. 3. YAML Tags: The library primarily respects the json tag for field naming and structure [1][2]. While it may not explicitly process yaml tags for field naming by default, you can configure the reflector to use different tags for field names by setting the FieldNameTag configuration (e.g., to "yaml") [5]. Since this library only generates schemas, you will need a separate validator package (such as santhosh-tekuri/jsonschema or others) to perform the actual validation of your JSON data against the schema produced by invopop/jsonschema [6].

Citations:


Reject invalid interactsh-eviction values before propagation.

jsonschema:"minimum=1" only affects schema generation; YAML/JSON unmarshalling still stores values like -1 in Template.InteractshEviction. That value then reaches line 558, and EvictionFromSeconds converts it to 0, silently using the global TTL instead of rejecting the invalid template config. Reject values < 0 here while keeping 0 as the unset/default state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/templates/compile.go` at line 558, Validate Template.InteractshEviction
before assigning it to options.InteractshEviction in the compile flow: reject
values less than 0, while preserving 0 as the unset/default state and allowing
positive values. Ensure invalid configurations return an error instead of
reaching EvictionFromSeconds and being converted to the global TTL.

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.

Per template customisation of interactsh timers/timeouts

1 participant