Introduction to Nuclei Templates
How Nuclei Templates Work
In this article, we explore how Nuclei templates work, detailing the process of creating and configuring custom vulnerability tests. You'll learn the fundamentals, from setting up the basic information and crafting precise HTTP requests to using variables, payloads, matchers, and extractors for dynamic testing. Additionally, a practical example demonstrates how to simulate a vulnerable server and detect a vulnerability using a custom Nuclei template.
What is a Nuclei Template?
A Nuclei template is a YAML-formatted file that, by filling in specific sections, allows you to standardize and automate vulnerability detection without having to rewrite code each time. In this article, we will work with the most common protocol for templates: HTTP.
- Basic Information: Identifier, name, author, severity, and description.
- Requests: Configuration of HTTP requests that will be sent to the target.
- Matchers: Conditions that must be met in the response to determine if the vulnerability is present.
- Extractors (Optional): Tools to extract and diplay additional information from the response.
Explanation of the Template Parts
Information Section (info)
This section categorizes the template using metadata fields:
- id: Unique identifier for the template.
- severity: Indicates the vulnerability’s criticality (e.g., low, medium, high, critical).
- reference: URLs to supporting documentation, CVEs, or external resources.
- tags: Keywords that facilitate searching and classification.
Example:
id: example-vulnerability-id
info:
name: "Generic Vulnerability Example"
author: "AuthorName"
severity: "medium"
description: "Detects a generic vulnerability in a web application."
reference:
- "https://example.com/vulnerability-details"
tags: ["example", "web", "vulnerability"]
Request Definition
For HTTP-based templates, this section specifies the HTTP requests to be executed:
- method: HTTP method (e.g., GET, POST, PUT, DELETE).
- path: Target endpoint(s), which may include dynamic variables (e.g.,
{{BaseURL}}
). - headers, body, timeout, retries: Additional request parameters.
Example:
requests:
- method: POST
path:
- "{{BaseURL}}/api/login"
headers:
Content-Type: "application/json"
User-Agent: "Mozilla/5.0 (compatible; Nuclei)"
body: '{"username": "admin", "password": "admin"}'
timeout: 5
retries: 2
Variables and Placeholders
Variables can be predefined or custom variables to enable dynamic configuration:
- Predefined variables: e.g.,
{{BaseURL}}
automatically resolves to the target host. - Custom variables: User-defined values that can be reused across multiple sections.
- Functions: Variables may incorporate functions (e.g.,
base64_decode("QXRsYW5zZWMK")
) to modify data at runtime.
Supported protocols: dns, http, headless, and network.
Payloads
Payloads allow injection tests or brute-force methods by defining lists of values—such as strings, special characters, or patterns. Each payload is iterated over and injected into designated request parameters.
Example:
These values are referenced in requests using placeholders (e.g., {{username}}
).
Matchers
Matchers validate parts of the protocol response using different techniques. There are seven primary matcher types:
- status: Compares HTTP status codes.
- size: Validates content length.
- word: Searches for specific words or phrases.
- regex: Matches text using regular expressions.
- binary: Detects hexadecimal or binary sequences.
- dsl: Evaluates expressions via a domain-specific language for complex conditions (very handy and used).
- xpath: Extracts data from structured XML/HTML using XPath.
Matchers can be combined with logical conditions (AND/OR), and negative matchers can be specified using negative: true
.
Extractors
Extractors capture specific data from responses for further processing or reuse. They include:
- regex: Uses regular expressions to extract patterns.
- kval: Retrieves key–value pairs from headers or cookies.
- json: Applies JQ-like syntax to extract data from JSON responses.
- xpath: Uses XPath to extract elements or attributes from HTML/XML.
- dsl: Evaluates expressions to compute values (e.g., body length).
Dynamic extractors (with internal: true
) capture runtime values—such as CSRF tokens—for use in subsequent requests.
Advanced Features
- Multiple Requests: Chain several HTTP requests to simulate multi-step interactions (e.g., extract a CSRF token from a GET request for use in a subsequent POST request).
- Custom Scripts: Process extracted values inline (e.g., convert a token to lowercase before reuse).
- Attack Modes: Define payload injection strategies such as battering ram, clusterbomb, or pitchfork.
Practical Guide: Vulnerable Web Server and Nuclei Template
Start the vulnerable docker
We are going to be using this server with a couple vulnerabilities to test and practice our new acquired knowledge about Nuclei templates.
To run the docker: docker run -p 1234:8000 -it appsecco/dsvw
Once it has started, you can access it and see a couple of vulnerabilities to test and create templates for. The first one is the following example.
In this first example there is a boolean SQLI which can be detected as the table fills or not, so because that the matcher selected to detect this vulnerability is a dsl looking at the length of the response body.
Create a Nuclei Template to Detect the Boolean SQLI
To find the length of the password, we will use a payload (ranging from 1 to 9) hardcoded in the template, although a file could also be used for more dynamic payloads.
Create a file called something like BSQLI-dsvw.yaml
with the following content:
id: boolean-sqli-password-extract
info:
name: SQLite Boolean-Based SQL Injection - Password Extraction
author: yourName
severity: critical
tags: ["sqli","sqlite","boolean-based"]
http:
- method: GET
path:
- "{{BaseURL}}?id=2%20AND%20SUBSTR((SELECT%20password%20FROM%20users%20WHERE%20name%3D%27admin%27)%2C1%2C1)%3D%27{{length}}%27"
payloads:
length:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
matchers-condition: and
matchers:
- type: dsl
dsl:
- "len(body)>1350 && status_code==200"
Run Nuclei with the Template
With the server running at http://localhost:1234
, open another terminal and run:
Nuclei will send a requests to the server and upon finding correct length, will display a result indicating that the test was successful and the payload that corresponds to the length of the password.
Conclusion
Whether you are a bug hunter, a pentester or even working from the defensive side, having Nuclei in your arsenal of tools will make your work more efficient and allow you to focus on more complex vulnerabilities to be discovered.
This example was done using basic templates, but you can go much further. You can create your own templates tailored to your needs, contribute to the community by sharing new rules, integrate Nuclei into CI/CD flows, or use the templates to perform continuous monitoring of your infrastructure.
Stay safe. Stay smart. Stay secure.