Skip to main content
HTTP is the most commonly used protocol in Nuclei templates for testing web applications, APIs, and HTTP-based services.

Basic HTTP request

The simplest HTTP template sends a GET request:
id: basic-http-example

info:
  name: Basic HTTP Request
  author: pdteam
  severity: info

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

HTTP request methods

Simple method definition

method
string
HTTP method to use for the request.Supported methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE, CONNECT
http:
  - method: POST
    path:
      - "{{BaseURL}}/api/data"

Multiple paths

Test multiple endpoints with the same request configuration:
http:
  - method: GET
    path:
      - "{{BaseURL}}/admin"
      - "{{BaseURL}}/administrator"
      - "{{BaseURL}}/wp-admin"
      - "{{BaseURL}}/phpmyadmin"
    
    stop-at-first-match: true
    matchers:
      - type: status
        status:
          - 200

Request formats

Path-based requests

Simple URL path definition:
http:
  - method: GET
    path:
      - "{{BaseURL}}/.git/config"
      - "{{BaseURL}}/.env"
    
    matchers:
      - type: word
        words:
          - "[core]"
          - "DB_PASSWORD"
        condition: or

Raw HTTP requests

Full control over the HTTP request:
http:
  - raw:
      - |
        GET /api/v1/users HTTP/1.1
        Host: {{Hostname}}
        User-Agent: CustomScanner/1.0
        Accept: application/json
        Authorization: Bearer {{token}}
    
    matchers:
      - type: word
        words:
          - '"users"'
Raw requests give you complete control over headers, method, and body. Use them for:
  • Custom header manipulation
  • Testing with specific User-Agents
  • Exact request replication from Burp/ZAP

Request components

Headers

headers
object
Custom headers to include in the request.
http:
  - method: GET
    path:
      - "{{BaseURL}}/api"
    headers:
      X-API-Key: "test123"
      Content-Type: "application/json"
      Authorization: "Bearer {{token}}"

Body

body
string
Request body for POST, PUT, PATCH requests.
http:
  - method: POST
    path:
      - "{{BaseURL}}/api/login"
    headers:
      Content-Type: application/json
    body: |
      {
        "username": "admin",
        "password": "{{password}}"
      }

Request example with all components

id: api-authentication-test

info:
  name: API Authentication Test
  author: researcher
  severity: medium

http:
  - method: POST
    path:
      - "{{BaseURL}}/api/v2/auth/login"
    
    headers:
      Content-Type: application/json
      X-Client-Version: "1.0"
      Origin: "{{RootURL}}"
    
    body: |
      {
        "username": "[email protected]",
        "password": "password123",
        "remember": true
      }
    
    matchers:
      - type: word
        words:
          - '"token"'
          - '"success":true'
        condition: and
    
    extractors:
      - type: json
        name: auth_token
        json:
          - ".data.token"

Variables in HTTP templates

Use template variables for dynamic values:
id: variables-example

info:
  name: HTTP Variables Example
  author: pdteam
  severity: info

variables:
  random_id: "{{rand_int(1000, 9999)}}"
  encoded_host: "{{base64(Hostname)}}"
  timestamp: "{{unix_time()}}"

http:
  - raw:
      - |
        GET /?id={{random_id}} HTTP/1.1
        Host: {{Hostname}}
        X-Custom-Header: {{encoded_host}}
        X-Timestamp: {{timestamp}}
    
    matchers:
      - type: status
        status:
          - 200

Payloads and fuzzing

Simple payloads

payloads
object
Define payload sets for parameter fuzzing.
http:
  - method: GET
    path:
      - "{{BaseURL}}/api?username={{username}}"
    
    payloads:
      username:
        - admin
        - administrator
        - root
        - test
    
    attack: batteringram

Attack types

Inserts same payload into all positions simultaneously:
http:
  - method: GET
    path:
      - "{{BaseURL}}/search?q={{payload}}&type={{payload}}"
    
    payloads:
      payload:
        - "'"
        - '"><script>alert(1)</script>'
    
    attack: batteringram

External payload files

http:
  - method: GET
    path:
      - "{{BaseURL}}/api?key={{key}}"
    
    payloads:
      key: keys.txt  # One payload per line
    
    attack: batteringram

Multi-step HTTP requests

Chain requests together with data passing:
id: multi-step-auth

info:
  name: Multi-Step Authentication Flow
  author: researcher
  severity: high

http:
  - method: GET
    path:
      - "{{BaseURL}}/login"
    
    extractors:
      - type: regex
        name: csrf_token
        internal: true
        regex:
          - 'name="csrf_token" value="([^"]+)"'
        group: 1
  
  - method: POST
    path:
      - "{{BaseURL}}/login"
    
    headers:
      Content-Type: application/x-www-form-urlencoded
    
    body: "username=admin&password=test&csrf_token={{csrf_token}}"
    
    extractors:
      - type: regex
        name: session_id
        internal: true
        regex:
          - 'session_id=([A-Za-z0-9]+)'
        group: 1
  
  - method: GET
    path:
      - "{{BaseURL}}/admin/users"
    
    headers:
      Cookie: "session_id={{session_id}}"
    
    matchers:
      - type: word
        words:
          - "User Management"
          - "Delete User"
        condition: and

Request conditions

Execute requests based on previous results:
http:
  - method: GET
    path:
      - "{{BaseURL}}/api/version"
    
    matchers:
      - type: word
        name: version_1
        words:
          - '"version":"1.'
    
    matchers-condition: or
  
  - method: GET
    path:
      - "{{BaseURL}}/api/v1/exploit"
    
    req-condition: true
    matchers:
      - type: word
        words:
          - "vulnerable"

Advanced features

Automatically reuse cookies across requests in the same template.
http:
  - method: POST
    path:
      - "{{BaseURL}}/login"
    body: "user=admin&pass=test"
    cookie-reuse: true
  
  - method: GET
    path:
      - "{{BaseURL}}/admin"  # Cookies from login are sent
Disable automatic cookie handling.
http:
  - method: GET
    path:
      - "{{BaseURL}}/api"
    disable-cookie: true

Redirects

redirects
boolean
default:false
Follow HTTP redirects.
http:
  - method: GET
    path:
      - "{{BaseURL}}/redirect"
    redirects: true
    max-redirects: 3
host-redirects
boolean
default:false
Only follow redirects to the same host.
http:
  - method: GET
    path:
      - "{{BaseURL}}/external-redirect"
    host-redirects: true

Race conditions

race
boolean
default:false
Send multiple requests simultaneously for race condition testing.
http:
  - method: POST
    path:
      - "{{BaseURL}}/api/coupon"
    body: "code=DISCOUNT50"
    
    race: true
    race_count: 10
    
    matchers:
      - type: word
        words:
          - "Coupon applied successfully"

Unsafe/Raw HTTP

unsafe
boolean
default:false
Use rawhttp engine for non-RFC compliant requests.
http:
  - raw:
      - |
        GET /path HTTP/1.1
        Host: {{Hostname}}
        Transfer-Encoding: chunked
        Content-Length: 4
        
        DATA
    
    unsafe: true

Request size limits

max-size
integer
Maximum response body size to read (in bytes).
http:
  - method: GET
    path:
      - "{{BaseURL}}/large-file.zip"
    max-size: 10240  # 10KB

Concurrency

threads
integer
default:1
Number of concurrent requests (enables connection pooling).
http:
  - method: GET
    path:
      - "{{BaseURL}}/api?id={{id}}"
    
    payloads:
      id: ids.txt  # Large list
    
    threads: 10

HTTP response parts

Specify which part of the response to match/extract:
body
string
Response body content (default)
matchers:
  - type: word
    part: body
    words:
      - "admin"
header
string
Response headers
matchers:
  - type: word
    part: header
    words:
      - "X-Powered-By: PHP"
all
string
Headers and body combined
matchers:
  - type: regex
    part: all
    regex:
      - "Server: Apache.*\n.*admin panel"
status_code
integer
HTTP status code
matchers:
  - type: dsl
    dsl:
      - "status_code == 200"
raw
string
Complete raw response including status line
request
string
The sent request

Authentication

Basic Auth

http:
  - method: GET
    path:
      - "{{BaseURL}}/admin"
    headers:
      Authorization: "Basic {{base64('admin:password')}}"

Bearer Token

http:
  - method: GET
    path:
      - "{{BaseURL}}/api/data"
    headers:
      Authorization: "Bearer {{token}}"

Digest Auth

http:
  - method: GET
    path:
      - "{{BaseURL}}/protected"
    
    digest-username: admin
    digest-password: secret

Complete examples

id: http-get-example

info:
  name: Basic HTTP GET
  author: pdteam
  severity: info

http:
  - method: GET
    path:
      - "{{BaseURL}}/robots.txt"
    
    matchers:
      - type: word
        words:
          - "Disallow:"

Testing tips

Use -debug flag to see full request/response:
nuclei -t template.yaml -u https://example.com -debug
Comment out matchers-condition to see which matchers are firing:
# matchers-condition: and
matchers:
  - type: status
    status:
      - 200
  - type: word
    words:
      - "admin"
See why templates didn’t match:
nuclei -t template.yaml -u https://example.com -v

Next steps

DNS protocol

DNS queries and enumeration

Matchers

Complete matcher reference

Extractors

Data extraction guide

Helper functions

DSL functions for HTTP

Build docs developers (and LLMs) love