Skip to main content
Operators are the core components that determine whether a template matches a vulnerability and what data to extract from responses. Nuclei provides two types of operators: matchers and extractors.

What are operators?

Operators process protocol responses to identify vulnerabilities and extract relevant information. Every protocol request can include operators to analyze responses.

Matchers

Identify if a response indicates a vulnerability

Extractors

Extract specific data from responses for analysis or chaining

Operators structure

Operators are embedded within protocol requests:
id: operators-example

info:
  name: Operators Example
  author: pdteam
  severity: info

http:
  - method: GET
    path:
      - "{{BaseURL}}/admin"
    
    matchers:
      - type: status
        status:
          - 200
      
      - type: word
        words:
          - "Admin Panel"
          - "Dashboard"
    
    extractors:
      - type: regex
        regex:
          - "version:\\s*([0-9.]+)"

Matchers

Matchers define the conditions that must be met for a template to report a finding.

Matcher types

Nuclei supports several matcher types:
Match HTTP status codes:
matchers:
  - type: status
    status:
      - 200
      - 302
      - 403

Matcher conditions

Control how multiple matcher values are evaluated:
matchers:
  - type: word
    words:
      - "error"
      - "warning"
      - "exception"
    condition: or  # Match if ANY word is found

Matchers condition

When using multiple matchers in a request, control their relationship:
id: matchers-condition-example

info:
  name: Multiple Matchers with AND Condition
  author: pdteam
  severity: high

http:
  - method: GET
    path:
      - "{{BaseURL}}/admin"
    
    matchers-condition: and  # ALL matchers must match
    matchers:
      - type: status
        status:
          - 200
      
      - type: word
        words:
          - "Admin Panel"
      
      - type: word
        words:
          - "Welcome, admin"
Default matchers-condition is or - the template matches if ANY matcher succeeds.

Matcher parts

Specify which part of the response to match against:
matchers:
  - type: word
    part: body
    words:
      - "vulnerable"
  
  - type: word
    part: header
    words:
      - "Server: Apache"
  
  - type: regex
    part: all
    regex:
      - "(?i)error"
Available parts vary by protocol:
  • HTTP: body, header, all, cookie, request, response
  • DNS: question, answer, authority, additional, all
  • Network: data, request, all

Negative matchers

Invert matcher logic:
matchers:
  - type: word
    words:
      - "protected"
      - "authentication required"
    negative: true  # Match if words are NOT found

Case-insensitive matching

matchers:
  - type: word
    words:
      - "admin"
      - "dashboard"
    case-insensitive: true  # Matches Admin, ADMIN, admin, etc.

Named matchers

Assign names to matchers for workflow conditions:
matchers:
  - name: wordpress-detected
    type: word
    words:
      - "wp-content"
      - "wp-includes"
  
  - name: admin-panel-exposed
    type: status
    status:
      - 200

Extractors

Extractors pull specific data from responses for reporting or passing to subsequent requests.

Extractor types

Extract using regular expressions:
http-value-share-template-1.yaml
extractors:
  - type: regex
    part: body
    name: extracted
    regex:
      - 'href="(.*)"'
    group: 1

Internal extractors

Extract values for use in subsequent requests without displaying them:
http-matcher-extractor-dy-extractor.yaml (partial)
extractors:
  - type: regex
    internal: true
    part: body_1
    name: absolutePath
    regex:
      - '<a href="(/domains)">'
    group: 1
  - type: regex
    internal: false
    part: body_2
    name: title
    regex:
      - '<title[^>]*>([^<]+)</title>'
    group: 1
Internal extractors ( internal: true) are not shown in output but can be referenced in subsequent requests using their name.

Extractor regex groups

Extract specific capture groups from regex:
extractors:
  - type: regex
    name: version
    regex:
      - "Apache/([0-9.]+)\\s+\\(([^)]+)\\)"
    group: 1  # Extracts only the version number

Combining matchers and extractors

Use both to identify vulnerabilities and extract proof:
id: combined-operators

info:
  name: Combined Matchers and Extractors
  author: pdteam
  severity: medium

http:
  - method: GET
    path:
      - "{{BaseURL}}/config.php"
    
    matchers:
      - type: word
        words:
          - "DB_PASSWORD"
          - "DB_USER"
        condition: and
    
    extractors:
      - type: regex
        regex:
          - "DB_PASSWORD\\s*=\\s*['\"]([^'\"]+)"
          - "DB_USER\\s*=\\s*['\"]([^'\"]+)"

DSL helper functions

Nuclei provides powerful DSL functions for advanced matching:

String functions

matchers:
  - type: dsl
    dsl:
      - "contains(body, 'admin')"
      - "contains_any(body, 'error', 'warning', 'exception')"
      - "contains_all(body, 'admin', 'panel')"
      - "starts_with(body, '<?php')"
      - "ends_with(body, '</html>')"
      - "len(body) > 1000"
      - "to_lower(header['server']) == 'apache'"

Response functions

matchers:
  - type: dsl
    dsl:
      - "status_code == 200"
      - "content_length > 5000"
      - "duration < 500"
      - "contains(all_headers, 'X-Powered-By: PHP')"

Logical operators

matchers:
  - type: dsl
    dsl:
      - "status_code == 200 && contains(body, 'admin')"
      - "status_code >= 400 || len(body) == 0"
      - "!(contains(body, 'error'))"

Match-all mode

Require all values in a matcher to match:
matchers:
  - type: word
    words:
      - "admin"
      - "dashboard"
      - "logout"
    match-all: true  # All words must be present

Operator execution order

Understanding execution order helps build effective templates:
1

Request execution

Protocol request is sent to target
2

Response received

Full response is captured and stored
3

Extractors run first

All extractors process the response and extract values
4

Variables updated

Extracted values are added to the template context
5

Matchers evaluate

Matchers run against the response and extracted values
6

Result generated

If matchers succeed, a result event is created

Practical examples

API endpoint discovery

id: api-endpoint-discovery

info:
  name: API Endpoint Discovery
  author: pdteam
  severity: info

http:
  - method: GET
    path:
      - "{{BaseURL}}/api/v1/users"
    
    matchers:
      - type: dsl
        dsl:
          - "status_code == 200"
          - "contains(content_type, 'application/json')"
        condition: and
    
    extractors:
      - type: json
        json:
          - ".users[] | .email"
          - ".users[] | .id"

Version detection

id: version-detection

info:
  name: Server Version Detection
  author: pdteam
  severity: info

http:
  - method: GET
    path:
      - "{{BaseURL}}"
    
    matchers:
      - type: regex
        part: header
        regex:
          - "Server: .*"
    
    extractors:
      - type: kval
        kval:
          - server
      
      - type: regex
        part: header
        regex:
          - "Server: ([^\r\n]+)"

Sensitive data exposure

id: sensitive-data-check

info:
  name: Sensitive Data Exposure
  author: pdteam
  severity: high

http:
  - method: GET
    path:
      - "{{BaseURL}}/.env"
      - "{{BaseURL}}/config.yml"
    
    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      
      - type: word
        words:
          - "PASSWORD"
          - "SECRET"
          - "API_KEY"
        condition: or
    
    extractors:
      - type: regex
        regex:
          - "(?i)(password|secret|api_key)\\s*[:=]\\s*['\"]?([^'\"\r\n]+)"

Best practices

Be specific

Use precise matchers to avoid false positives

Use DSL wisely

Combine multiple conditions in DSL for complex logic

Name extractors

Always name extractors for easy reference in multi-step templates

Test thoroughly

Validate matchers against various responses to ensure accuracy

Common pitfalls

Avoid these common mistakes:
  1. Using match-all: true when you mean condition: and
  2. Forgetting to escape special characters in regex
  3. Not specifying part for matchers, leading to unexpected results
  4. Using extractors without internal: true in multi-step templates
  5. Forgetting that Go regex doesn’t support lookaheads/lookbehinds

Matchers deep dive

Detailed matcher and extractor guide

Protocols

Protocol-specific operators

Templates

Template structure basics

Build docs developers (and LLMs) love