Variables in Nuclei allow you to define reusable values, perform computations, and create dynamic template behavior. They can be defined at the template level, extracted from responses, or computed using DSL helper functions.
Variable types
Nuclei supports three types of variables:
Template variables
Defined at the template level and available to all requests:
id : variables-example
info :
name : Variables Example
author : pdteam
severity : info
variables :
a1 : "value"
a2 : "{{base64('{{Host}}')}}"
port : 8080
http :
- raw :
- |
GET / HTTP/1.1
Host: {{Hostname}}:{{port}}
Test: {{a1}}
Another: {{a2}}
Extracted from responses using extractors and available in subsequent requests:
http :
- method : POST
path :
- "{{BaseURL}}/api/login"
body : "username=admin&password=test"
extractors :
- type : regex
name : token
internal : true
regex :
- "token=([a-zA-Z0-9]+)"
- method : GET
path :
- "{{BaseURL}}/api/data"
headers :
Authorization : "Bearer {{token}}"
Dynamic variables
Generated at runtime using payloads or helper functions:
http :
- path :
- "{{BaseURL}}/user/{{username}}"
payloads :
username :
- admin
- test
- guest
Built-in variables
Nuclei provides several built-in variables for common use cases:
The input URL including protocol and port. Example: https://example.com:443
The hostname from the input URL. Example: example.com
The port from the input URL. Example: 443
The path from the input URL. Example: /api/v1/users
The root URL without path. Example: https://example.com
The URL scheme (http/https). Example: https
Fully Qualified Domain Name. Example: www.example.com
Generates a unique Interactsh URL for OOB testing. Example: c59p8k2a0000kg8a0000hg.oast.fun
Using variables in requests
Variable scope
Variables have different scopes depending on where they’re defined:
Global scope
variables :
global_var : "value"
http :
- method : GET
path :
- "{{BaseURL}}/{{global_var}}" # Available in all requests
Request scope
Extracted variables are available in subsequent requests:
http :
- method : GET
path :
- "{{BaseURL}}/step1"
extractors :
- type : regex
name : request_var
internal : true
regex :
- "id=([0-9]+)"
- method : GET
path :
- "{{BaseURL}}/step2?id={{request_var}}" # Available after extraction
Computing variables
Use DSL helper functions to compute values:
variables :
encoded_host : "{{base64(Host)}}"
current_time : "{{unixtime()}}"
random_string : "{{randstr(16)}}"
md5_hash : "{{md5(Host)}}"
Variables support nested helper functions: {{base64(to_lower(Host))}}
Payloads as variables
Payloads create variables that iterate over values:
Single Payload
Multiple Payloads (Clusterbomb)
Payload from File
http :
- method : GET
path :
- "{{BaseURL}}/api/{{endpoint}}"
payloads :
endpoint :
- users
- posts
- comments
Constants
Constants are scalar values that don’t support helper functions:
constants :
API_VERSION : "v1"
MAX_RETRIES : 3
TIMEOUT : 30
http :
- method : GET
path :
- "{{BaseURL}}/api/{{API_VERSION}}/data"
Flow variables
In flow-based templates, use JavaScript to manipulate variables:
flow : |
// Set variables
set("custom_var", "value");
// Get variables from template context
let emails = template["emails"];
// Iterate and set
for (let email of emails) {
set("current_email", email);
http(2);
}
http :
- method : GET
path :
- "{{BaseURL}}"
extractors :
- type : regex
name : emails
internal : true
regex :
- "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+ \\ .[a-zA-Z]{2,}"
- method : GET
path :
- "{{BaseURL}}/user?email={{current_email}}"
Real-world examples
Multi-Step Authentication
Dynamic Subdomain Enumeration
API Version Testing
id : auth-flow
info :
name : Multi-Step Auth Flow
author : pdteam
severity : info
variables :
username : "admin"
password : "test123"
http :
- method : GET
path :
- "{{BaseURL}}/csrf"
extractors :
- type : regex
name : csrf_token
internal : true
regex :
- 'csrf_token"\\s*value="([^"]+)'
- method : POST
path :
- "{{BaseURL}}/login"
body : |
username={{username}}&password={{password}}&csrf={{csrf_token}}
extractors :
- type : kval
name : session_id
internal : true
kval :
- sessionid
- method : GET
path :
- "{{BaseURL}}/admin/panel"
headers :
Cookie : "sessionid={{session_id}}"
Variable precedence
When multiple variables have the same name, Nuclei follows this precedence (highest to lowest):
Flow-set variables (set() function)
Extracted variables (from extractors)
Payload variables
Template variables
Built-in variables
Best practices
Use descriptive names - Choose clear, self-documenting variable names
Minimize global variables - Keep variables scoped to where they’re needed
Extract only what’s needed - Don’t extract large amounts of unnecessary data
Use internal extractors - Mark intermediate values as internal
Validate variable formats - Use matchers to verify extracted data
Document complex variables - Add comments for computed or transformed values
Avoid name collisions - Don’t reuse built-in variable names
Common patterns
Conditional variables
variables :
port : "{{Port}}"
scheme : "{{Scheme}}"
target : "{{scheme}}://{{Host}}:{{port}}"
Timestamp-based variables
variables :
timestamp : "{{unixtime()}}"
nonce : "{{randstr(16)}}"
signature : "{{md5(timestamp + nonce)}}"
Encoded variables
variables :
payload : "<script>alert(1)</script>"
url_encoded : "{{urlencode(payload)}}"
base64_encoded : "{{base64(payload)}}"
html_encoded : "{{html_escape(payload)}}"
Extractors Extract data from responses
Helper Functions DSL helper functions
Flow Control JavaScript-based flow
Payloads Payload configuration