Developing Custom Nuclei Templates to Detect Insecure API Endpoints and Common API Vulnerabilities (e.g., BOLA, Broken Authentication)

Developing Custom Nuclei Templates for API Vulnerabilities

Directly addressing the core of API security, custom Nuclei templates provide unparalleled flexibility for identifying specific insecure API endpoints and common vulnerabilities like Broken Object Level Authorization (BOLA) and Broken Authentication. Standard scanners often miss application-specific logic flaws, making bespoke Nuclei checks essential for a robust security assessment.

Understanding Nuclei Template Structure

A Nuclei template is fundamentally a YAML file that defines a series of requests and matching conditions. These templates dictate how Nuclei interacts with a target and what constitutes a finding. The basic structure involves an `id` for unique identification, `info` containing metadata (name, author, severity, tags), and a `http` section defining the actual HTTP request and response matching logic. Consider a basic template structure:

id: custom-api-check
info:
  name: Custom API Endpoint Check
  author: yourname
  severity: info
  description: "Detects a specific API endpoint."
  tags: [api, custom]

http:
  - raw:
      - |
        GET /api/v1/status HTTP/1.1
        Host: {{Hostname}}
        User-Agent: Nuclei/2.x
        Accept: */*

    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - "status: ok"
        part: body
This template checks for a `/api/v1/status` endpoint and expects a 200 OK response containing "status: ok" in the body. This foundation is extended for more complex vulnerability detection.

Detecting Broken Object Level Authorization (BOLA)

BOLA, or Insecure Direct Object Reference (IDOR), occurs when an application provides direct access to objects based on user-supplied input without proper authorization checks. An attacker can manipulate this input (e.g., an ID in a URL or request body) to access resources they shouldn't. To craft a Nuclei template for BOLA, we need to simulate an unauthorized attempt to access a resource belonging to another user. This typically involves: 1. Identifying an API endpoint that uses an object ID in its path or body. 2. Crafting a request to access *your own* legitimate object. 3. Modifying the object ID to one you *do not* own but might guess (e.g., incrementing an integer ID, trying common UUIDs, or using Zondex to discover potential ID patterns from exposed services). 4. Checking the response for unauthorized access indicators (e.g., 401/403 status codes for authorized attempts, or successful access to the *other* user's data indicating a flaw). Here's an example Nuclei template for BOLA:

id: bola-user-data-access
info:
  name: Broken Object Level Authorization - User Data Access
  author: yourname
  severity: high
  description: "Attempts to access another user's data by manipulating ID."
  reference:
    - https://owasp.org/API-Security/editions/2023/en/0x23-b03-broken-object-level-authorization/
  tags: [api, bola, idor, authorization]

variables:
  # Legitimate ID that the attacker might have access to (or a placeholder)
  my_user_id: "12345"
  # Hypothetical target ID that the attacker should NOT have access to
  target_user_id: "12346" 
  # A valid authentication token (replace with a real token for testing)
  auth_token: "Bearer eyJhbGciOiJIUzI1Ni..." 

http:
  - raw:
      - |
        GET /api/v1/users/{{target_user_id}}/profile HTTP/1.1
        Host: {{Hostname}}
        User-Agent: Nuclei/2.x
        Accept: application/json
        Authorization: {{auth_token}}

    matchers:
      - type: status
        status:
          - 200 # If we get a 200 OK, it means we accessed unauthorized data
        # Exclude 401/403, as those indicate proper authorization controls
        # If the app returns 200 with another user's data, it's vulnerable.
      - type: word
        words:
          - "user_id\": \"{{target_user_id}}\"" # Look for the target ID in the response body
          - "email\":\"[email protected]" # Or other indicators of the *other* user's data
        condition: and
        part: body
In this template, `my_user_id` and `target_user_id` are variables. The request attempts to fetch the profile of `target_user_id` using an `auth_token` that presumably belongs to `my_user_id`. A `200 OK` status and the presence of `target_user_id` (or other identifying data of the target user) in the response body would indicate a BOLA vulnerability. If the application correctly returns a 401/403 or data pertaining only to `my_user_id`, then it's not vulnerable to this specific check. For complex API security testing, integrating Nuclei scans with comprehensive platforms like Secably can help manage discovered vulnerabilities and automate subsequent security workflows.

Identifying Broken Authentication

Broken Authentication covers a broad range of weaknesses, including weak passwords, exposed credentials, weak session management, and improper handling of authentication attempts (e.g., lack of rate limiting allowing brute-force). Custom Nuclei templates can target specific patterns.

Weak/Default Credentials

Many systems are deployed with default or easily guessable credentials. A Nuclei template can test for these.

id: default-api-credentials
info:
  name: Default API Credentials Check
  author: yourname
  severity: critical
  description: "Checks for common default credentials on API login endpoints."
  reference:
    - https://owasp.org/API-Security/editions/2023/en/0x23-b02-broken-authentication/
  tags: [api, authentication, default-creds]

http:
  - raw:
      - |
        POST /api/v1/auth/login HTTP/1.1
        Host: {{Hostname}}
        User-Agent: Nuclei/2.x
        Content-Type: application/json
        Accept: application/json
        Content-Length: {{len("{\"username\":\"{{username}}\",\"password\":\"{{password}}\"}}}

        {"username":"{{username}}","password":"{{password}}"}

    payloads:
      username:
        - "admin"
        - "user"
        - "test"
        - "root"
      password:
        - "admin"
        - "password"
        - "123456"
        - "test"
        - "root"
        - "changeme"
        - "" # Empty password

    matchers-condition: or
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - "success\":true"
          - "authenticated\":true"
          - "token\":" # Presence of a JWT or session token
        condition: or
        part: body
This template uses a `payloads` section to iterate through common usernames and passwords against a `/api/v1/auth/login` endpoint. A successful login (indicated by a 200 status or specific words in the response body) flags the vulnerability.

Brute-Force Detection (Limited Scope)

While a full-fledged brute-force attack is often outside Nuclei's primary scope for single templates, you can use it to detect potential lack of rate limiting by observing multiple failed login attempts and checking for the absence of blocking mechanisms. Routing such requests through a tool like GProxy can also help monitor the responses in real-time and observe any eventual blocking.

id: api-bruteforce-indicator
info:
  name: API Brute-Force Indicator - Lack of Rate Limiting
  author: yourname
  severity: medium
  description: "Sends multiple failed login attempts to check for rate limiting or lockout mechanisms."
  reference:
    - https://owasp.org/API-Security/editions/2023/en/0x23-b02-broken-authentication/
  tags: [api, authentication, bruteforce, ratelimit]

variables:
  target_username: "nonexistentuser"
  invalid_password: "invalidpassword123!"

http:
  - raw:
      - |
        POST /api/v1/auth/login HTTP/1.1
        Host: {{Hostname}}
        User-Agent: Nuclei/2.x
        Content-Type: application/json
        Accept: application/json
        Content-Length: {{len("{\"username\":\"{{target_username}}\",\"password\":\"{{invalid_password}}\"}}}

        {"username":"{{target_username}}","password":"{{invalid_password}}"}
    
    attack: times # Send the request multiple times
    req-condition: true # Always send this request
    times: 10 # Number of times to send the failed login attempt

    matchers-condition: and
    matchers:
      - type: status
        status:
          - 401 # Expecting unauthorized status for failed login attempts
          - 400
      - type: word
        words:
          - "invalid credentials"
          - "login failed"
        condition: or
        part: body
      - type: dsl # Check if no rate limit or lockout message appears after multiple attempts
        dsl: |
          !contains(body, 'Too many requests') && !contains(body, 'Account locked') && !contains(body, 'Rate limit exceeded')
This template sends 10 identical failed login attempts. The `dsl` matcher tries to assert that no rate limiting or account lockout messages appear, which would indicate a potential vulnerability to brute-force attacks. This isn't a definitive proof of brute-force success but an indicator of missing protection.

Running Custom Templates

Once a custom template is developed, execute it using the `nuclei` command-line tool. To scan a single target with a custom template:

nuclei -u https://api.example.com -t /path/to/your/custom-bola-template.yaml
To scan a list of targets:

nuclei -l targets.txt -t /path/to/your/custom-authentication-template.yaml
Example Output for a BOLA finding:

[FTL] 2024-04-26 10:00:00 - Run Nuclei on targets from file targets.txt
[bola-user-data-access] https://api.example.com/api/v1/users/12346/profile [bola-user-data-access]
This concise output indicates a hit, confirming the template found its specified conditions. The power of custom Nuclei templates lies in their ability to pinpoint application-specific flaws that generic scanners often overlook, making them an indispensable tool in any pentester's arsenal for API security.