Writing Custom Nuclei Templates to Detect API Mass Assignment Vulnerabilities

Crafting Custom Nuclei Templates for API Mass Assignment Detection

Detecting API mass assignment vulnerabilities requires a targeted approach, often beyond generic scanning. Custom Nuclei templates enable security researchers and red teamers to specifically probe API endpoints for these logical flaws by manipulating request parameters and observing application responses. This methodology focuses on simulating attacker-controlled input to overwrite unintended object properties, a common oversight in API development where frameworks automatically bind HTTP request parameters to internal code variables without sufficient filtering.

Understanding Mass Assignment in APIs

Mass assignment, sometimes called autobinding or object injection depending on the framework, occurs when an application automatically maps incoming client-supplied data (e.g., JSON or form data) directly to an internal data model or object. If not properly restricted, an attacker can include parameters for sensitive, unintended fields in their request, thereby modifying properties they should not have access to. Common examples include manipulating is_admin, role, user_id, or even financial values like total_price. The core issue lies in inadequate property filtering, allowing attackers to guess common sensitive fields or leverage available source code to identify them.

Identifying Potential Target APIs

Before writing a template, identify API endpoints that process user-supplied data, particularly those related to creating or updating user profiles, orders, or any resource where an authenticated user might interact with their own data or data they manage. Look for HTTP POST, PUT, or PATCH requests. Analyze application traffic, documentation (if available), or even JavaScript files for endpoint paths and expected JSON/form structures. Burp Suite or other proxies are invaluable for this reconnaissance, capturing and analyzing requests that send data to the backend.

Nuclei Template Structure Fundamentals

Nuclei templates are YAML-based definitions that specify how requests are sent and responses are processed. A basic HTTP template consists of several key blocks: id, info, and one or more protocol blocks (e.g., http) containing requests, matchers, and optionally extractors.


id: api-mass-assignment-test
info:
  name: API Mass Assignment - Admin Privilege Escalation
  author: your-pentester-handle
  tags: api, mass-assignment, privilege-escalation, critical
  severity: high
  description: |
    Tests for mass assignment vulnerability on user update endpoint by attempting
    to set 'is_admin' or 'role' fields to privileged values.
    This template attempts to escalate privileges by adding sensitive parameters
    to a standard user update request.

http:
  - raw:
      - |
        POST /api/v1/user/profile HTTP/1.1
        Host: {{Hostname}}
        User-Agent: Nuclei-Scanner/1.0
        Content-Type: application/json
        Accept: application/json
        Authorization: Bearer {{token}}
        
        {
          "username": "testuser",
          "email": "[email protected]",
          "is_admin": true,
          "role": "admin"
        }
    matchers-condition: or
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - '"is_admin":true'
          - '"role":"admin"'
        part: body
        condition: or
      - type: word
        words:
          - 'Permission denied'
          - 'Unauthorized'
        part: body
        condition: and
        negative: true

The id field provides a unique identifier. The info block contains metadata like the template's name, author, severity, and a description. The http block defines the HTTP request details.

Crafting the HTTP Request for Mass Assignment

The http section is where the attack vector is defined. For API mass assignment, you'll typically use POST, PUT, or PATCH methods. The raw directive within the http block provides complete control over the HTTP request, including headers and the body. This is crucial for injecting malicious parameters.

In the example above:

  • POST /api/v1/user/profile HTTP/1.1 specifies the method and path.
  • Host: {{Hostname}} uses the dynamic Hostname variable.
  • Content-Type: application/json indicates the body format, which is common for modern APIs.
  • Authorization: Bearer {{token}} is a placeholder. In a real scenario, you'd either run this template against an already authenticated session, use an extracted token from a prior request in a workflow, or manually provide a valid token.
  • The JSON body includes legitimate user update fields (username, email) alongside potentially sensitive fields like "is_admin": true and "role": "admin". The goal is to see if the API processes these unauthorized fields.

For parameter variations or fuzzing, Nuclei supports payloads with different attack types like clusterbomb, batteringram, and pitchfork, allowing systematic testing of different sensitive parameters. For example, you might create a list of common administrative-level roles (`admin`, `administrator`, `privileged`, `root`) and iterate through them for the `role` field.

Matching for Successful Assignment

matchers are used to determine if the response indicates a successful vulnerability. Nuclei offers various matcher types, including status, word, regex, and dsl.

In the template:

  • - type: status with status: - 200 checks for a successful HTTP status code. While a 200 OK doesn't always mean success, it's often a prerequisite.
  • - type: word with words: - '"is_admin":true' - '"role":"admin"' directly searches the response body for evidence that the sensitive fields were processed as intended. The part: body directive ensures the matcher operates on the response body.
  • matchers-condition: or means if any of the top-level matchers are true, the template is considered a match.
  • A negative matcher (`negative: true`) is crucial for reducing false positives. The example includes a negative matcher for phrases like 'Permission denied' or 'Unauthorized', meaning if these words *are* present, the match should fail, indicating the mass assignment likely didn't succeed.

Combining multiple matchers with logical conditions (and/or) increases accuracy. For instance, you might require a 200 status code AND the presence of the updated sensitive field in a subsequent GET request to the profile endpoint.

Extracting Relevant Information

extractors can pull specific data from the response, such as updated tokens, IDs, or the value of the assigned sensitive field. This is particularly useful in multi-step workflows where extracted data from one request is fed into a subsequent one.

For example, if the API response reflects the updated is_admin status, an extractor could capture this:


    extractors:
      - type: json
        json:
          - '.is_admin'
        name: new_admin_status

This would extract the value of is_admin from the JSON response, naming it new_admin_status for output or further use.

Real-World Scenario: Profile Update Privilege Escalation

Consider an API endpoint /api/v1/user/settings that allows a user to update their display name and notification preferences. A legitimate request might look like this:


POST /api/v1/user/settings HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer [user_token]

{
  "displayName": "NewUserName",
  "notificationsEnabled": true
}

A mass assignment attempt would involve adding a sensitive, unauthorized parameter to this request:


POST /api/v1/user/settings HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer [user_token]

{
  "displayName": "NewUserName",
  "notificationsEnabled": true,
  "is_admin": true,
  "user_role": "administrator",
  "account_type": "premium"
}

The custom Nuclei template would send this modified payload and look for indicators in the response (or a follow-up request) that these sensitive fields were accepted and processed.

Executing Custom Templates with Nuclei

Once the .yaml template file is saved (e.g., api-mass-assignment.yaml), running it against a target is straightforward. Nuclei offers various command-line options.

To scan a single URL:


nuclei -u https://api.example.com -t api-mass-assignment.yaml -v -o results.txt

Here:

  • -u specifies the target URL.
  • -t points to your custom template.
  • -v enables verbose output, which is helpful for debugging and seeing request/response details.
  • -o saves the output to a file.

For scanning multiple targets from a list:


nuclei -l targets.txt -t api-mass-assignment.yaml -o mass_assignment_findings.json -json

The targets.txt file should contain one URL per line. Using -json outputs results in JSON format, which is useful for automation and parsing.

To validate your template syntax before running:


nuclei -validate -t api-mass-assignment.yaml

This ensures the YAML is correctly formatted and the Nuclei engine can parse it.

Interpreting Nuclei Output

A successful match in Nuclei's output indicates that your custom template conditions were met. For mass assignment, this means the API likely processed the unauthorized parameter. The verbose output (`-v`) or debug mode (`-debug`) can show the exact requests and responses, allowing for manual verification of the vulnerability. Look for the specific words or regex patterns you defined in your matchers within the response body. If the response contains the injected sensitive field and its manipulated value (e.g., "is_admin": true), it's a strong indicator of a mass assignment vulnerability. If the API returns an error or rejects the unknown parameters, the template should not fire, or your negative matchers should prevent a false positive.

Always follow up Nuclei findings with manual verification using tools like Burp Suite or curl to confirm the vulnerability and assess its true impact.