> ## Documentation Index
> Fetch the complete documentation index at: https://docs.projectdiscovery.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Headless Protocol

> Learn about using a headless browser with Nuclei

Nuclei supports automation of a browser with simple DSL. Headless browser engine can be fully customized and user actions can be scripted allowing complete control over the browser. This allows for a variety of unique and custom workflows.

```yaml theme={null}
# Start the requests for the template right here
headless:
```

## Actions

An action is a single piece of Task for the Nuclei Headless Engine. Each action manipulates the browser state in some way, and finally leads to the state that we are interested in capturing.

Nuclei supports a variety of actions. A list of these Actions along with their arguments are given below:

### navigate

Navigate visits a given URL. url field supports variables like `{{BaseURL}}`, `{{Hostname}}` to customize the request fully.

```yaml theme={null}
action: navigate
args: 
  url: "{{BaseURL}}
```

### script

Script runs a JavaScript code on the current browser page. At the simplest level, you can just provide a `code` argument with the JS snippet you want to execute, and it will be run on the page.

```yaml theme={null}
action: script
args:
  code: () => alert(document.domain)
```

<Warning>
  The <code>code</code> property strictly requires a function reference. Direct expressions or values are invalid and will not work. Always use a function.

  **Incorrect:**

  ```yaml theme={null}
  action: script
  args:
    code: alert(document.domain) # ❌ This is NOT a function reference
  ```

  **Correct:**

  ```yaml theme={null}
  action: script
  args:
    code: () => alert(document.domain) # ✅ This is a function reference
  ```
</Warning>

Suppose you want to run a matcher on a JS object to inspect its value. This type of data extraction use cases are also supported with nuclei headless. As an example, let's say the application sets an object called `window.random-object` with a value, and you want to match on that value.

```yaml theme={null}
- action: script
  args:
    code: () => window.random-object
  name: script-name
...
matchers:
  - type: word
    part: script-name
    words:
      - "some-value"
```

Nuclei supports running some custom Javascript, before the page load with the `hook` argument. This will always run the provided Javascript, before any of the pages load.

The example provided hooks `window.alert` so that the alerts that are generated by the application do not stop the crawler.

```yaml theme={null}
- action: script
  args:
    code: () => (function() { window.alert=function(){} })()
    hook: true
```

This is one use case, there are many more use cases of function hooking such as DOM XSS Detection and Javascript-Injection based testing techniques. Further examples are provided on examples page.

### click

Click simulates clicking with the Left-Mouse button on an element specified by a selector.

```yaml theme={null}
action: click
args: 
  by: xpath
  xpath: /html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[2]/input
```

Nuclei supports a variety of selector types, including but not limited to XPath, Regex, CSS, etc. For more information about selectors, see [here](#selectors).

### rightclick

RightClick simulates clicking with the Right-Mouse button on an element specified by a selector.

```yaml theme={null}
action: rightclick
args: 
  by: xpath
  xpath: /html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[2]/input
```

### text

Text simulates typing something into an input with Keyboard. Selectors can be used to specify the element to type in.

```yaml theme={null}
action: text
args: 
  by: xpath
  xpath: /html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[2]/input
  value: username
```

### screenshot

Screenshots takes the screenshots of a page and writes it to disk. It supports both full page and normal screenshots.

```yaml theme={null}
action: screenshot
args: 
  to: /root/test/screenshot-web
```

If you require full page screenshot, it can be achieved with `fullpage: true` option in the args.

```yaml theme={null}
action: screenshot
args: 
  to: /root/test/screenshot-web
  fullpage: true
```

### time

Time enters values into time inputs on pages in RFC3339 format.

```yaml theme={null}
action: time
args: 
  by: xpath
  xpath: /html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[2]/input
  value: 2006-01-02T15:04:05Z07:00
```

### select

Select performs selection on an HTML Input by a selector.

```yaml theme={null}
action: select
args: 
  by: xpath
  xpath: /html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[2]/input
  selected: true
  value: option[value=two]
  selector: regex
```

### files

Files handles a file upload input on the webpage.

```yaml theme={null}
action: files
args: 
  by: xpath
  xpath: /html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[2]/input
  value: /root/test/payload.txt
```

### waitfcp

WaitFCP waits for the first piece of meaningful content, such as text or an image, indicating that the page is becoming useful.

```yaml theme={null}
action: waitfcp
```

### waitfmp

WaitFMP waits for the First Meaningful Paint event, allowing users to proceed when content is visually ready.

```yaml theme={null}
action: waitfmp
```

### waitdom

WaitDOM waits for the `DOMContentLoaded` event, indicating that the HTML has been loaded and parsed, but without waiting for stylesheets, images, and subframes to finish loading.

```yaml theme={null}
action: waitdom
```

### waitload

WaitLoad waits the entire page, including dependent resources like stylesheets and images, has been fully loaded.

```yaml theme={null}
action: waitload
```

### waitidle

WaitIdle waits until the page completely stopped making network requests and reaches a network idle state, indicating that all resources have been loaded.

```yaml theme={null}
action: waitidle
```

### waitstable

WaitStable waits until the page is stable for *N* duration *(default is `1s`)*.

```yaml theme={null}
action: waitstable
args:
  duration: 5s
```

### waitdialog

WaitDialog will wait for a JavaScript dialog (`alert`, `confirm`, `prompt`, or `onbeforeunload`) to be initialized and then automatically accept it.

```yaml theme={null}
action: waitdialog
name: alert
args:
  max-duration: 5s # (Optional. Default 10s.)
```

This action is useful for detecting triggered XSS payloads with a high level of accuracy and a low rate of false positives.

<Note>
  The `name` property MUST be explicitly defined to ensure the output variable is available for later use by `matchers` or `extractors` wihtin your template. See the example [here](/templates/protocols/headless-examples#xss-detection).
</Note>

**Output variables:**

* **NAME** *(boolean)*, indicator of JavaScript dialog triggered.
* **NAME\_type** *(string)*, dialog type (`alert`, `confirm`, `prompt`, or `onbeforeunload`).
* **NAME\_message** *(string)*, displayed message dialog.

### getresource

GetResource returns the src attribute for an element.

```yaml theme={null}
action: getresource
name: extracted-value-src
args: 
  by: xpath
  xpath: /html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[2]/input
```

### extract

Extract extracts either the Text for an HTML Node, or an attribute as specified by the user.

The below code will extract the Text for the given XPath Selector Element, which can then also be matched upon by name `extracted-value` with matchers and extractors.

```yaml theme={null}
action: extract
name: extracted-value
args: 
  by: xpath
  xpath: /html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[2]/input
```

An attribute can also be extracted for an element. For example -

```yaml theme={null}
action: extract
name: extracted-value-href
args: 
  by: xpath
  xpath: /html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[2]/input
  target: attribute
  attribute: href
```

### setmethod

SetMethod overrides the method for the request.

```yaml theme={null}
action: setmethod
args: 
  part: request
  method: DELETE
```

### addheader

AddHeader adds a header to the requests / responses. This does not overwrite any pre-existing headers.

```yaml theme={null}
action: addheader
args: 
  part: response # can be request too
  key: Content-Security-Policy
  value: "default-src * 'unsafe-inline' 'unsafe-eval' data: blob:;"
```

### setheader

SetHeader sets a header in the requests / responses.

```yaml theme={null}
action: setheader
args: 
  part: response # can be request too
  key: Content-Security-Policy
  value: "default-src * 'unsafe-inline' 'unsafe-eval' data: blob:;"
```

### deleteheader

DeleteHeader deletes a header from requests / responses.

```yaml theme={null}
action: deleteheader
args: 
  part: response # can be request too
  key: Content-Security-Policy
```

### setbody

SetBody sets the body for a request / response.

```yaml theme={null}
action: setbody
args: 
  part: response # can be request too
  body: '{"success":"ok"}'
```

### waitevent

WaitEvent waits for an event to trigger on the page.

```yaml theme={null}
action: waitevent
args: 
  event: 'Page.loadEventFired'
```

The list of events supported are listed [here](https://github.com/go-rod/rod/blob/master/lib/proto/definitions.go).

### keyboard

Keyboard simulates a single key-press on the keyboard.

```yaml theme={null}
action: keyboard
args: 
  keys: '\r' # this simulates pressing enter key on keyboard
```

`keys` argument accepts key-codes.

### debug

Debug adds a delay of 5 seconds between each headless action and also shows a trace of all the headless events occurring in the browser.

> Note: Only use this for debugging purposes, don't use this in production templates.

```yaml theme={null}
action: debug
```

### sleep

Sleeps makes the browser wait for a specified duration in seconds. This is also useful for debugging purposes.

```yaml theme={null}
action: sleep
args:
  duration: 5
```

## Selectors

Selectors are how nuclei headless engine identifies what element to execute an action on. Nuclei supports getting selectors by including a variety of options -

| Selector             | Description                                         |
| -------------------- | --------------------------------------------------- |
| `r` / `regex`        | Element matches CSS Selector and Text Matches Regex |
| `x` / `xpath`        | Element matches XPath selector                      |
| `js`                 | Return elements from a JS function                  |
| `search`             | Search for a query (can be text, XPATH, CSS)        |
| `selector` (default) | Element matches CSS Selector                        |

## Matchers / Extractor Parts

Valid `part` values supported by **Headless** protocol for Matchers / Extractor are -

| Value             | Description                     |
| ----------------- | ------------------------------- |
| request           | Headless Request                |
| `<out_names>`     | Action names with stored values |
| raw / body / data | Final DOM response from browser |

## Example Headless Templates

An example headless template to automatically login into DVWA is provided below -

```yaml theme={null}
id: dvwa-headless-automatic-login

info:
  name: DVWA Headless Automatic Login
  author: pdteam
  severity: high

headless:
  - steps:
      - args:
          url: "{{BaseURL}}/login.php"
        action: navigate
      - action: waitload
      - args:
          by: xpath
          xpath: /html/body/div/div[2]/form/fieldset/input
        action: click
      - action: waitload
      - args:
          by: xpath
          value: admin
          xpath: /html/body/div/div[2]/form/fieldset/input
        action: text
      - args:
          by: xpath
          xpath: /html/body/div/div[2]/form/fieldset/input[2]
        action: click
      - action: waitload
      - args:
          by: xpath
          value: password
          xpath: /html/body/div/div[2]/form/fieldset/input[2]
        action: text
      - args:
          by: xpath
          xpath: /html/body/div/div[2]/form/fieldset/p/input
        action: click
      - action: waitload
    matchers:
      - part: resp
        type: word
        words:
          - "You have logged in as"
```

<Tip>
  More complete examples are provided [here](/templates/protocols/headless-examples).
</Tip>
