Skip to main content
This guide provides an in-depth look at all components that make up a Nuclei template, from required fields to advanced configurations.

Template hierarchy

A Nuclei template follows this structure:
id: template-identifier

info:
  # Metadata block

variables:
  # Template-level variables

constants:
  # Immutable values

flow: |
  # Execution flow logic (optional)

[protocol]:
  # One or more protocol blocks
  - # Request definition
    matchers:
      # Match conditions
    extractors:
      # Data extraction

self-contained: false
stop-at-first-match: false

Required sections

Template ID

id
string
required
Unique identifier for the template across all templates.Rules:
  • Use lowercase letters, numbers, and hyphens
  • Start with a letter
  • Be descriptive but concise
  • Use CVE ID format for CVE templates: CVE-2021-12345
  • Use technology prefixes: wordpress-, jenkins-, apache-
Examples:
id: CVE-2021-44228
id: wordpress-xmlrpc-listmethods
id: nginx-version-detect

Info block

info
object
required
Contains all template metadata and classification information.

Required info fields

info:
  name: Human-Readable Template Name
  author: researcher1,researcher2
  severity: critical
name
string
required
Purpose: Describes what the template detectsGuidelines:
  • Use title case
  • Be specific but not verbose
  • Mention the vulnerability type
  • Include product name if relevant
Examples:
  • “Apache Log4j Remote Code Execution”
  • “Exposed Git Repository”
  • “WordPress Plugin SQL Injection”
author
string
required
Purpose: Credits the template creator(s)Format: Comma-separated usernames (no spaces)
author: pdteam
author: researcher1,researcher2,researcher3
severity
string
required
Purpose: Indicates the risk levelValues:
  • info - Informational, no direct security impact
  • low - Minor security issues
  • medium - Moderate vulnerabilities
  • high - Serious vulnerabilities
  • critical - Severe, immediate risk
severity: high

Optional info fields

info:
  description: |
    Detailed explanation of the vulnerability,
    its impact, and detection methodology.
    Can be multi-line.
Use pipe (|) for multi-line descriptions.

Protocol blocks

Every template needs at least one protocol section defining the requests to send.

Supported protocols

HTTP

Web application testing

DNS

DNS queries and zone enumeration

Network/TCP

Raw TCP connections

SSL/TLS

Certificate and SSL checks

WebSocket

WebSocket connections

WHOIS

Domain registration data

JavaScript

Custom protocol logic

Code

Execute code snippets

File

Local file system scanning

Basic protocol structure

http:
  - method: GET
    path:
      - "{{BaseURL}}/path"
    
    matchers:
      - type: word
        words:
          - "success"
Each protocol can have multiple requests:
http:
  - # Request 1
    method: GET
    path:
      - "{{BaseURL}}/api/v1"
  
  - # Request 2
    method: POST
    path:
      - "{{BaseURL}}/api/v2"

Variables and constants

Variables

variables
object
Define dynamic values that can use DSL functions and are evaluated at runtime.
variables:
  random_id: "{{rand_int(100000, 999999)}}"
  encoded_host: "{{base64(Host)}}"
  timestamp: "{{unix_time()}}"
Use in requests:
http:
  - path:
      - "{{BaseURL}}/api?id={{random_id}}"

Constants

constants
object
Define static values that never change.
constants:
  api_version: "v1"
  default_user: "admin"
  max_retries: 3

Matchers

Define conditions that must be met for a template to report a match.

Matcher types

matchers:
  - type: word
    words:
      - "admin panel"
      - "dashboard"
    condition: or
    part: body
Searches for exact strings in the response.

Matcher conditions

matchers-condition: and  # ALL matchers must match
matchers:
  - type: status
    status:
      - 200
  - type: word
    words:
      - "vulnerable"
matchers-condition: or  # ANY matcher can match (default)
matchers:
  - type: word
    words:
      - "admin"
  - type: word
    words:
      - "administrator"

Extractors

Extract data from responses for reporting or use in subsequent requests.

Extractor types

extractors:
  - type: regex
    name: api_key
    regex:
      - 'api[_-]?key["\']?\s*[:=]\s*["\']?([a-zA-Z0-9-_]+)'
    group: 1
Extract using regular expression groups.

Internal extractors

extractors:
  - type: regex
    name: csrf_token
    internal: true  # Don't show in output
    regex:
      - 'csrf_token"\s*value="([^"]+)"'
    group: 1
Use in subsequent request:
http:
  - # Request 1 - extract token
    method: GET
    path:
      - "{{BaseURL}}/login"
    extractors:
      - type: regex
        name: csrf_token
        internal: true
        regex:
          - 'name="csrf_token" value="([^"]+)"'
        group: 1
  
  - # Request 2 - use token
    method: POST
    path:
      - "{{BaseURL}}/login"
    body: "username=admin&password=test&csrf_token={{csrf_token}}"

Global options

Self-contained

self-contained
boolean
default:false
Template doesn’t require external input; URLs are included in the template.
id: specific-target-check

self-contained: true

http:
  - raw:
      - |
        GET http://specific-target.com/api HTTP/1.1
        Host: specific-target.com

Stop at first match

stop-at-first-match
boolean
default:false
Stop template execution after first successful match.
stop-at-first-match: true

http:
  - path:
      - "{{BaseURL}}/admin"
      - "{{BaseURL}}/administrator"
      - "{{BaseURL}}/wp-admin"
Stops after finding the first accessible admin panel.

Flow control

flow
string
Advanced execution control using JavaScript-like syntax.
flow: |
  http("probe");
  if (template["probe_status"] == true) {
    http("exploit");
  }
See Flow Control for details.

Multi-protocol templates

Combine multiple protocols in one template:
id: multi-protocol-check

info:
  name: DNS and HTTP Combined Check
  author: researcher
  severity: info

dns:
  - name: "{{FQDN}}"
    type: A
    matchers:
      - type: word
        words:
          - "IN\tA"

http:
  - method: GET
    path:
      - "{{BaseURL}}"
    matchers:
      - type: status
        status:
          - 200

Request chaining

Pass data between requests:
http:
  - method: GET
    path:
      - "{{BaseURL}}/api/session"
    extractors:
      - type: json
        name: session_id
        internal: true
        json:
          - ".session.id"
  
  - method: GET
    path:
      - "{{BaseURL}}/api/data"
    headers:
      X-Session-ID: "{{session_id}}"
    matchers:
      - type: word
        words:
          - "authenticated"

Part definitions

Each protocol exposes different parts for matching/extraction:

HTTP parts

  • body - Response body (default)
  • header - Response headers
  • all - Headers + body
  • status_code - HTTP status code
  • content_length - Response length
  • raw - Complete raw response

DNS parts

  • raw - Full DNS response (default)
  • answer - Answer section
  • question - Question section
  • ns - Nameserver section
  • extra - Additional section

Network parts

  • data - Received data (default)
  • raw - Complete interaction
  • request - Sent request

Template examples

id: admin-panel-detect

info:
  name: Admin Panel Detection
  author: researcher
  severity: info

http:
  - method: GET
    path:
      - "{{BaseURL}}/admin"
    
    matchers:
      - type: word
        words:
          - "admin panel"
          - "administrator"
        condition: or

Next steps

Protocol guides

Deep dive into specific protocols

Matchers reference

Complete matcher documentation

Extractors reference

All extractor types explained

Helper functions

DSL function reference

Build docs developers (and LLMs) love