Skip to main content
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 variables

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:
{{BaseURL}}
string
The input URL including protocol and port.Example: https://example.com:443
{{Hostname}}
string
The hostname from the input URL.Example: example.com
{{Host}}
string
Alias for {{Hostname}}.
{{Port}}
string
The port from the input URL.Example: 443
{{Path}}
string
The path from the input URL.Example: /api/v1/users
{{RootURL}}
string
The root URL without path.Example: https://example.com
{{Scheme}}
string
The URL scheme (http/https).Example: https
{{FQDN}}
string
Fully Qualified Domain Name.Example: www.example.com
{{interactsh-url}}
string
Generates a unique Interactsh URL for OOB testing.Example: c59p8k2a0000kg8a0000hg.oast.fun

Using variables in requests

http:
  - method: GET
    path:
      - "{{BaseURL}}/api"
    headers:
      X-API-Key: "{{api_key}}"
      User-Agent: "Scanner/{{version}}"

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:
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

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):
  1. Flow-set variables (set() function)
  2. Extracted variables (from extractors)
  3. Payload variables
  4. Template variables
  5. Built-in variables

Best practices

  1. Use descriptive names - Choose clear, self-documenting variable names
  2. Minimize global variables - Keep variables scoped to where they’re needed
  3. Extract only what’s needed - Don’t extract large amounts of unnecessary data
  4. Use internal extractors - Mark intermediate values as internal
  5. Validate variable formats - Use matchers to verify extracted data
  6. Document complex variables - Add comments for computed or transformed values
  7. 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

Build docs developers (and LLMs) love