# Azion Bot Manager Lite

import DocButton from '~/components/webkit/DocButton.vue';

# Overview

Azion Bot Manager Lite v0.2.0 is a serverless integration available on Azion Marketplace, built with a function in the Firewall. It analyzes incoming requests and assigns each one a score based on a set of predefined rules. When the score reaches or exceeds the configured threshold, the function executes the defined action. If the score stays below the threshold, the request proceeds normally (`allow` is the default action). Available actions: `allow`, `deny`, `drop`, `redirect`, `custom_html`, `random_delay`, and `hold_connection`. The integration detects suspicious traffic and malicious bots, including web scraping and brute force attacks.

## Solution Details

The function evaluates each request and assigns a score based on predefined rules. You configure the action and threshold in the JSON Args. If the score reaches or exceeds the threshold, the function executes the configured action. Otherwise, the Firewall Rules Engine continues to execute normally.

## Rules

Bot Manager Lite evaluates each request against 26 rules. Each matched rule increments the request score by a fixed amount. When the cumulative score reaches or exceeds the configured `threshold`, the function executes the configured `action`.

| Rule ID | Description | Score Increment | Class |
|---|---|---|---|
| 1 | `${http_user_agent}` is empty | 8 | Bad bot signatures |
| 2 | `${http_content_type}` is empty AND `${request_body}` is not empty | 8 | Bad bot signatures |
| 3 | `${http_referer}` is empty AND `${request_method}` is POST, PUT, PATCH, or DELETE | 6 | Malicious intent |
| 4 | `${http_user_agent}` contains the string `Dalvik` | 4 | Bad bot signatures |
| 5 | `${http_user_agent}` contains the string `Trident` | 6 | Bad bot signatures |
| 6 | `${http_user_agent}` contains the string `Headless` | 6 | Bad bot signatures |
| 7 | `${http_user_agent}` is longer than 200 characters or shorter than 10 characters | 4 | Bad bot signatures |
| 8 | `${http_user_agent}` matches a known bad bot user agent | 8 | Scripted bots |
| 9 | `${http_accept}` is empty | 8 | Bad bot signatures |
| 10 | `${http_accept_language}` is empty | 8 | Bad bot signatures |
| 11 | `${http_range}` is empty | 6 | Malicious intent |
| 12 | `${request_method}` is `TRACE` | 8 | Malicious intent |
| 13 | `${http_content_length}` is empty AND `${request_method}` is POST, PUT, or PATCH | 8 | Bad bot signatures |
| 14 | Client IP is found in a configured reputation Network List | 6 | Reputation Intelligence |
| 15 | `${request_method}` is POST, PUT, or PATCH AND `${cookie_az_botm}` is absent | 8 | Malicious browser behavior |
| 16 | `${request_method}` is POST, PUT, or PATCH AND `${cookie_az_asm}` is absent | 8 | Malicious browser behavior |
| 17 | Session cookie integrity violation | 16 | Malicious browser behavior |
| 18 | `${http_sec_fetch_mode}` is empty | 4 | Malicious intent |
| 19 | `${http_sec_fetch_dest}` is empty | 4 | Malicious intent |
| 20 | `${http_sec_fetch_site}` is empty | 4 | Malicious intent |
| 21 | `${server_fingerprint}` matches an entry in `bad_fingerprint_list` | 32 | Malicious browser behavior |
| 22 | `${http_user_agent}` matches a known outdated browser user agent | 6 | Bad bot signatures |
| 23 | `${server_protocol}` is HTTP/1.0 or HTTP/1.1 | 6 | Scripted bots |
| 24 | `${geoip_asn}` matches a known cloud provider ASN | 4 | Cloud provider |
| 25 | `${http_user_agent}` matches a known headless browser user agent | 4 | Bad bot signatures |
| 26 | `${http_user_agent}` matches a known scripted client user agent | 8 | Bad bot signatures |

:::note
Rules 15, 16, and 17 rely on the built-in signed cookie validation system. On the first request from a browser, Bot Manager Lite sets two session cookies: `az_botm` (a unique request identifier) and `az_asm` (an HMAC-signed version of the same value). On subsequent requests, the function verifies that the two cookies are still consistent. A mismatch triggers rule 17.
:::

:::caution[Warning]
Rules 18–26 are new in v0.2.0 and ship without prior calibration. Depending on your traffic profile, they may generate false positives. Monitor your logs and use `disabled_rules` to exclude any rule that consistently matches legitimate traffic before switching from `allow` to a blocking action.
:::

You can disable specific rules using the `disabled_rules` argument. See [Setting up the function](#setting-up-the-function) for details.

## Function Details

The function is implemented in JavaScript and runs inside the Firewall. You configure its behavior through JSON Args. Logs are transmitted via Data Stream and Real-Time Events.

## Logs and Integration

You can configure the log records to capture a wide range of request data, excluding sensitive headers listed in the `log_headers` argument description. The solution also validates IP addresses using reputation Network Lists defined in the `reputation_network_lists` argument, increasing the threat score of matching requests.

### Setting up the function

The function accepts the following arguments:

| Variable | Type | Required | Description |
|---|---|---|---|
| `action` | String | Yes | The action to be taken by the function whenever the request's score is greater or equals the defined threshold. Possible values: `allow`, `deny`, `redirect`, `custom_html`, `drop`, `random_delay`, and `hold_connection`. Read more about [configuring actions](#configuring-actions) |
| `threshold` | Number | Yes | The maximum score that the request can reach before the function takes an action. If it has no value, the function won't take action |
| `disabled_rules` | Array of numbers | No | The rules to be disabled. If a rule is disabled, it won't be processed nor increment the request score |
| `internal_logs` | String | No | The logging class the function will use. Possible values:<br/>`"0"`: write logs if the request score is greater than 0 (default).<br/>`"1"`: write logs if the request score is greater than 0, or if the request is classified as a Good Bot.<br/>`"2"`: always write logs.<br/>`"3"`: never write logs.<br/>When this field has no value or an invalid value, the function uses the default value `"0"` |
| `log_headers` | Array of strings | No | Defines which request headers to include in the report log. The following headers are forbidden for security reasons: `authorization`, `cookie`, `proxy-authorization`, `set-cookie`, `x-csrf-token`, `x-api-key`, `x-amz-security-token`. **Note**: header values are stored with base64 encoding |
| `log_tag` | String | No | A tag to identify the function instance that generated the request in the logs. Use unique tags when running multiple instances |
| `reputation_network_lists` | Array of numbers | No | Network List IDs used to validate the client IP. If the IP is found in any list, the request score increases by 6 points per matched list. Default: empty list |
| `session_signature_key` | String | No | Signs the `az_asm` session cookie using HMAC to protect against cookie tampering. If this field has no value or an invalid value, the function uses the default value `az` |
| `should_write_warning_logs` | Boolean | No | Defines whether the function writes warning logs to Real-Time Events. Default value: `false` |
| `good_fingerprint_list` | Array of strings | No | Fingerprints with known good reputation. Requests matching any fingerprint in this list bypass all bot analysis rules entirely. Default: empty list |
| `bad_fingerprint_list` | Array of strings | No | Fingerprints with known bad reputation, evaluated by rule 21. A match adds 32 points to the request score. Default: empty list |
| `block_ai_bots` | Boolean | No | When set to `true`, requests identified as coming from known AI user-agents are automatically blocked, without running any other bot analysis rules. Default: `false` |

### Configuring actions

Azion Bot Manager Lite can execute 7 different actions whenever the request's score equals or exceeds the defined threshold. Read more about each one below:

1. `allow`: allows the continuation of the request. To enable this action, declare it as follows:

```json
  "action": "allow"
```

This action doesn't require any additional arguments.

If the score is less than the predetermined threshold, the request is processed — `allow` is the default action.

2. `deny`: delivers a standard *Status Code 403* response. To enable this action, declare it as follows:

```json
  "action": "deny"
```

This action doesn't require any additional arguments.

3. `drop`: terminates the request without a response to the user. To enable this action, declare it as follows:

```json
  "action": "drop"
```

This action doesn't require any additional arguments.

4. `redirect`: redirects the request to a new URL when the security threshold is reached. To enable this action, declare the variables as in the example:

```json
  "action": "redirect",
  "redirect_to": "http://xxxxxxxxxx.map.azionedge.net/"
```

Where `redirect_to` defines the new URL to redirect the request. If this field isn't filled or is filled with a value that isn't a string, the function behaves as if the `allow` action was enabled.

5. `custom_html`: delivers customized HTML content to the user when the threshold is violated. To enable this action, declare the variables as in the example:

```json
  "action": "custom_html",
  "custom_html": "This should be the custom HTML content",
  "custom_status_code": 418
```

Where `custom_html` defines the HTML content to be delivered and `custom_status_code` is the HTTP status code to return.

- If `custom_html` isn't filled or is filled with a value that isn't a string, the function behaves as if the `allow` action was enabled.
- If `custom_status_code` isn't filled or is filled with a value that isn't a number, the default value is *Status Code 200*.

6. `random_delay`: makes the function wait for a random period between 1 and 10 seconds before allowing the request to proceed. To enable this action, declare it as follows:

```json
  "action": "random_delay"
```

This action doesn't require any additional arguments.

7. `hold_connection`: holds the request, keeping the connection open for 1 minute before dropping it. To enable this action, declare it as follows:

```json
  "action": "hold_connection"
```

This action doesn't require any additional arguments.

:::note
Using any value other than `allow`, `deny`, `redirect`, `custom_html`, `drop`, `random_delay`, or `hold_connection` for the `action` variable causes the function to execute the default action: `allow`.
:::

<DocButton href="/en/documentation/products/guides/bot-manager-lite/" label="Go to the Bot Manager Lite installation guide" kind="secondary" size="medium" />

<DocButton href="/en/documentation/products/guides/bot-manager-lite-starter-kit/" label="Go to the Bot Manager Lite Starter Kit guide" kind="secondary" size="medium" />

<DocButton href="/en/documentation/products/guides/bot-manager-lite-integration-kit/" label="Go to the Bot Manager Lite Integration Kit guide" kind="secondary" size="medium" />