Building Custom Nuclei Templates for Automated API Endpoint Vulnerability Scanning
Automating API endpoint vulnerability scanning requires a highly adaptable tool, and Nuclei, with its customizable templating engine, fits the bill perfectly. Direct control over HTTP requests, response matching, and data extraction makes Nuclei an essential component in a modern pentester's toolkit for scaling security assessments across numerous APIs.
Nuclei Template Fundamentals for API Testing
A Nuclei template is a YAML-defined set of rules that describe how to interact with a target and what to look for in the response. For API endpoints, this means crafting precise HTTP requests that mimic typical client interactions, then defining specific conditions to identify vulnerabilities or interesting behaviors. The core components include `id`, `info` (name, author, severity, tags), `http` requests, and `matchers` or `extractors`.
Let's begin with a basic structure for an API template targeting an exposed administrative endpoint.
id: api-exposed-admin-panel
info:
name: Exposed API Admin Panel Detection
author: your-name
severity: high
description: Detects a potentially exposed administrative API endpoint.
tags: api, admin, exposure
requests:
- method: GET
path:
- "{{BaseURL}}/api/v1/admin/dashboard"
- "{{BaseURL}}/v2/admin"
- "{{BaseURL}}/api/admin/status"
matchers:
- type: status
status:
- 200
- type: word
words:
- "adminPanel"
- "adminDashboard"
part: body
condition: or
In this template, we define multiple paths using a list under `path`, which Nuclei will iterate through. The `matchers` section combines a status code check (200 OK) with keyword detection in the response body. If Nuclei receives a 200 status and finds either "adminPanel" or "adminDashboard" in the HTML or JSON body, it flags a potential hit.
Identifying API Endpoints and Crafting Requests
Before writing templates, you need endpoints. Reconnaissance is critical. Tools like
Zondex can assist in discovering exposed services and identifying potential API gateways or versioned endpoints across the internet. Once you have a list of targets, manual enumeration of Swagger/OpenAPI documentation, JavaScript files, or simply observing traffic through a proxy like Burp Suite will yield specific API paths and expected parameters.
Consider an API endpoint that handles user profile updates, typically a `POST` request with a JSON body.
id: api-user-profile-update-test
info:
name: User Profile Update via API - Test
author: your-name
severity: info
description: Tests a user profile update endpoint with sample data.
tags: api, post, user
requests:
- method: POST
path:
- "{{BaseURL}}/api/v1/user/profile"
headers:
Content-Type: application/json
Authorization: Bearer {{token}} # Placeholder for dynamic token
body: |
{
"firstName": "Nuclei",
"lastName": "Tester",
"email": "[email protected]"
}
unsafe: true # Required for HTTP POST bodies
matchers:
- type: status
status:
- 200
- type: word
words:
- "profile updated successfully"
- "firstName": "Nuclei"
part: body
condition: and
Here, `unsafe: true` is crucial for sending a raw `body`. The `Authorization` header includes a `{{token}}` variable. This demonstrates Nuclei's capability to handle dynamic authentication. While `{{token}}` here is a placeholder, more advanced templates can extract tokens from a login response using `extractors` and pass them to subsequent requests.
Detecting Common API Vulnerabilities
Custom Nuclei templates excel at detecting specific API vulnerabilities.
IDOR (Insecure Direct Object Reference)
IDOR often occurs when an application uses a user-supplied identifier to access an object directly without sufficient authorization checks.
id: api-idor-user-data
info:
name: API IDOR - User Data Access
author: your-name
severity: high
description: Attempts to access another user's data by manipulating a user ID in the API path.
tags: api, idor, authorization
requests:
- method: GET
path:
- "{{BaseURL}}/api/v1/users/123" # Original user ID
- "{{BaseURL}}/api/v1/users/124" # Attempting to access another user
headers:
Authorization: Bearer {{valid_user_token}}
stop-at-first-match: true
matchers:
- type: dsl
dsl:
- "status_code_1 == 200 && status_code_2 == 200 && contains(body_2, 'another_user_data_field')"
description: Both requests returned 200, and the second request contains identifiable data from a different user.
This template sends two `GET` requests: one for an assumed valid user ID (123) and another for a different ID (124). The `dsl` matcher allows for complex logical conditions, checking if both return `200` and if the response body for `124` contains data indicative of another user.
Sensitive Data Exposure
APIs can inadvertently expose sensitive data. This template attempts to find potential API keys or secrets in environment variable endpoints.
id: api-env-secret-exposure
info:
name: API Environment Variable Secret Exposure
author: your-name
severity: critical
description: Checks for API endpoints exposing environment variables, potentially containing secrets.
tags: api, exposure, secrets, env
requests:
- method: GET
path:
- "{{BaseURL}}/api/v1/env"
- "{{BaseURL}}/config/env"
- "{{BaseURL}}/admin/config/environment"
matchers:
- type: word
words:
- "AWS_ACCESS_KEY_ID"
- "API_SECRET_KEY"
- "DATABASE_URL"
part: body
condition: or
case-insensitive: true
This template targets common paths where environment variables might be exposed and looks for keywords associated with sensitive credentials.
Advanced Template Features: Chained Requests and Variables
Real-world API interactions often involve multiple steps. Nuclei's `workflow` and `variables` features allow for chaining requests, where the output of one request feeds into another. This is crucial for scenarios requiring authentication flows or multi-step attacks.
Let's illustrate extracting an authentication token and then using it.
id: api-auth-then-data-access
info:
name: Chained API Auth and Data Access
author: your-name
severity: medium
description: Authenticates to an API and then attempts to access user data using the obtained token.
tags: api, chained, auth, token
variables:
username: "testuser"
password: "testpassword"
http:
- raw:
- |
POST /api/v1/auth/login HTTP/1.1
Host: {{BaseURL}}
Content-Type: application/json
{
"username": "{{username}}",
"password": "{{password}}"
}
matchers:
- type: status
status:
- 200
extractors:
- type: regex
part: body
regex:
- '"token":"([a-zA-Z0-9\._-]+)"'
name: auth_token
- raw:
- |
GET /api/v1/user/profile HTTP/1.1
Host: {{BaseURL}}
Authorization: Bearer {{auth_token}}
matchers:
- type: status
status:
- 200
- type: word
words:
- "username": "{{username}}"
part: body
condition: and
Here, the first `http` request logs in and extracts `auth_token` using a regex. This `auth_token` is then used in the `Authorization` header of the subsequent `GET` request to retrieve profile data. The `variables` section defines `username` and `password` for easy modification.
For larger, more complex scanning campaigns, integrating Nuclei with platforms like
Secably can streamline the management of custom templates and automate the vulnerability validation lifecycle. When dealing with internal APIs or sensitive testing, routing all Nuclei traffic through a controlled proxy or VPN, potentially leveraging a solution like
GProxy, is often a requirement to ensure traffic monitoring and origin obfuscation.
Testing and Debugging Templates
Developing custom templates is an iterative process. Test your templates frequently against known good and bad targets.
Use the `-debug` flag for verbose output:
nuclei -t my-custom-api-template.yaml -u https://api.example.com -debug
This will show the full request and response, helping you pinpoint issues with paths, headers, body, matchers, or extractors. Pay close attention to how Nuclei resolves variables and processes `matchers`. The Nuclei Playground (a web-based tool) can also be invaluable for live template development and testing against sample HTTP responses.
Ensure your `matchers` are specific enough to avoid false positives but broad enough to catch variations. For example, when detecting error messages, consider common phrasing variations and case insensitivity. Regular expressions are powerful but can be brittle if not carefully crafted.
Building a robust library of custom Nuclei templates for your specific API ecosystem is an investment that pays dividends in automated, consistent, and scalable vulnerability discovery.