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

# Custom Rules

> Custom WAF rule authoring in Aegis

# Custom WAF Rules

Aegis supports three rule match modes: **Condition Builder** for structured field/operator/value rules, **Raw Regex** for advanced RE2-based pattern matching, and **Correlated** for multi-request [Mnemos](./mnemos) correlation rules.

<Frame>
  <img src="https://mintcdn.com/krakentechllc/QCb-hD7jjEnD8u8M/images/image-40.png?fit=max&auto=format&n=QCb-hD7jjEnD8u8M&q=85&s=5dfad58ff8583cb37048f9d8846caf79" alt="Image" width="2954" height="3194" data-path="images/image-40.png" />
</Frame>

***

## Rule Options

Every custom rule supports the following configuration:

| Option      | Description                                         |
| ----------- | --------------------------------------------------- |
| Name        | Rule display name                                   |
| Description | Detailed description of what the rule detects       |
| Category    | Classification category                             |
| Severity    | `low`, `medium`, `high`, or `critical`              |
| Action      | `block`, `allow`, `challenge`, `log`, or `redirect` |
| Enabled     | Toggle rule on/off                                  |
| Paranoia    | Paranoia level (1-4)                                |
| Tags        | Free-form tags for organization                     |
| OWASP IDs   | Associated OWASP identifiers                        |
| CVE IDs     | Associated CVE identifiers                          |

***

## Condition Builder Mode

Condition Builder is the standard rule-authoring flow. It supports multi-line field-based rules with `AND` / `OR` logic.

### Available Fields

| Field           | Description                      |
| --------------- | -------------------------------- |
| Request URI     | Full request URI                 |
| Request Path    | URL path component               |
| Query String    | URL query string                 |
| HTTP Method     | Request method (GET, POST, etc.) |
| Request Body    | Request body content             |
| User Agent      | User-Agent header value          |
| Host Header     | Host header value                |
| Content-Type    | Content-Type header value        |
| Referer         | Referer header value             |
| Source IP       | Client source IP address         |
| Any Header      | Match against any request header |
| Specific Header | Match against a named header     |
| Any Cookie      | Match against any cookie         |
| Specific Cookie | Match against a named cookie     |

### Available Operators

| Operator               | Description                        |
| ---------------------- | ---------------------------------- |
| `contains`             | Field contains the value           |
| `does not contain`     | Field does not contain the value   |
| `equals`               | Exact match                        |
| `does not equal`       | Not an exact match                 |
| `starts with`          | Field starts with the value        |
| `ends with`            | Field ends with the value          |
| `matches regex`        | RE2 regex match                    |
| `does not match regex` | RE2 regex non-match                |
| `is in list`           | Value is in a provided list        |
| `is not in list`       | Value is not in a provided list    |
| `greater than`         | Numeric comparison                 |
| `less than`            | Numeric comparison                 |
| `exists`               | Field is present (no value needed) |
| `does not exist`       | Field is absent (no value needed)  |
| `is IP in range`       | IP or CIDR range match             |

### Per-Condition Options

* **Case Sensitive** — toggle case sensitivity
* **Negate Result** — invert the condition match

### Examples

* Block requests where `Request Path` `contains` `/wp-admin`
* Block requests where `Specific Header` `matches regex` a malicious header pattern
* Allow requests where `Source IP` `is IP in range` `10.0.0.0/8`

***

## Raw Regex Mode

Raw Regex mode is for advanced rules and built-in style pattern matching. You provide a Go RE2 pattern and one or more request targets to inspect.

### Supported Targets

| Target       | Description          |
| ------------ | -------------------- |
| Path / URI   | Request path and URI |
| Query String | URL query parameters |
| Body         | Request body         |
| Headers      | All request headers  |
| Cookies      | All cookies          |
| User Agent   | User-Agent header    |

### Notes

* Patterns are compiled with Go's `regexp` engine (RE2 syntax)
* Inline flags such as `(?i)` are supported (server-side evaluation)
* Rules require both a pattern and at least one target

***

## Rule Testing

The rule tester uses the real backend WAF evaluation path — the same compiled Go regex engine and condition evaluator that runs in production. This is not a browser-side JavaScript approximation.

### Single Rule Test

Test an individual rule against a crafted request:

```text theme={null}
POST /api/v1/rules/test
```

```json theme={null}
{
  "rule": {
    "name": "Test SQLi",
    "match_mode": "regex",
    "pattern": "(?i)union\\s+select",
    "targets": ["query", "body"],
    "action": "block"
  },
  "request": {
    "method": "GET",
    "url": "/api/search?q=1 UNION SELECT 1,2,3",
    "headers": {"User-Agent": "Mozilla/5.0"},
    "body": "",
    "source_ip": "10.0.0.1"
  }
}
```

**Response:**

```json theme={null}
{
  "matched": true,
  "matched_target": "query",
  "matched_value": "UNION SELECT",
  "pattern_valid": true,
  "pattern_error": "",
  "processing_us": 42
}
```

The response includes:

| Field            | Description                                                                     |
| ---------------- | ------------------------------------------------------------------------------- |
| `matched`        | Whether the rule fired on the test request                                      |
| `matched_target` | Which request surface matched (path, query, body, headers, cookies, user-agent) |
| `matched_value`  | The specific value that triggered the match                                     |
| `pattern_valid`  | Whether the regex compiled successfully (RE2 syntax)                            |
| `pattern_error`  | Compilation error message if the pattern is invalid                             |
| `processing_us`  | Evaluation time in microseconds                                                 |

### Test All Rules

Test a crafted request against all enabled WAF rules to see which ones fire:

```text theme={null}
POST /api/v1/rules/test-all
```

```json theme={null}
{
  "request": {
    "method": "POST",
    "url": "/api/login",
    "headers": {"Content-Type": "application/json"},
    "body": "{\"user\":\"admin' OR 1=1--\"}",
    "source_ip": "10.0.0.1"
  }
}
```

**Response:**

```json theme={null}
{
  "matched": true,
  "tested_rules": 26,
  "matches": [
    {
      "rule_id": 1,
      "rule_name": "SQLi - Core",
      "category": "sqli",
      "severity": "high",
      "action": "block",
      "matched_target": "body",
      "matched_value": "OR 1=1"
    }
  ],
  "processing_us": 187
}
```

### Testing Correlation Rules

Correlated (Mnemos) rules can be tested by providing an array of requests that simulate a multi-request sequence:

```json theme={null}
{
  "rule": {
    "name": "Test Correlation",
    "match_mode": "correlated",
    "action": "block",
    "correlation_config": {
      "window_seconds": 60,
      "threshold": 2,
      "group_by": "source_ip"
    }
  },
  "requests": [
    {"method": "GET", "url": "/api/users", "source_ip": "10.0.0.1"},
    {"method": "GET", "url": "/api/config", "source_ip": "10.0.0.1"},
    {"method": "GET", "url": "/api/billing/export", "source_ip": "10.0.0.1"}
  ]
}
```

### What Gets Tested

| Rule Mode      | Evaluation                                                                               |
| -------------- | ---------------------------------------------------------------------------------------- |
| **Regex**      | Pattern compiled with Go RE2, tested against selected targets                            |
| **Conditions** | Each condition evaluated with the same field extraction and operator logic as production |
| **Correlated** | Request sequence fed into a real correlation store with compiled host rules              |

All three modes run through the same code paths as the live WAF — `engine.TestRule()` and `engine.Evaluate()` — so test results accurately predict production behavior.

***

## Rule Import (JSON / YAML)

Aegis supports bulk importing WAF rules from JSON or YAML files via the admin API. This allows you to share rule sets between Aegis instances, version-control your custom rules, or ingest community rule definitions.

### Endpoint

```text theme={null}
POST /api/v1/rules/import
Content-Type: multipart/form-data
```

Upload a `.json`, `.yaml`, or `.yml` file (max 4 MB). The format is auto-detected from the file extension.

### File Format

Rules can be provided in either a wrapped or direct array format:

**Wrapped format (JSON):**

```json theme={null}
{
  "version": "1.0",
  "rules": [
    {
      "name": "Block WordPress Admin",
      "category": "custom",
      "severity": "high",
      "action": "block",
      "enabled": true,
      "paranoia": 1,
      "match_mode": "conditions",
      "condition_logic": "AND",
      "conditions": [
        {
          "field": "Request Path",
          "operator": "contains",
          "value": "/wp-admin"
        }
      ],
      "description": "Block access to WordPress admin panel",
      "tags": ["wordpress"],
      "owasp_ids": [],
      "cve_ids": []
    }
  ]
}
```

**Wrapped format (YAML):**

```yaml theme={null}
version: "1.0"
rules:
  - name: Block WordPress Admin
    category: custom
    severity: high
    action: block
    enabled: true
    paranoia: 1
    match_mode: conditions
    condition_logic: AND
    conditions:
      - field: Request Path
        operator: contains
        value: /wp-admin
    description: Block access to WordPress admin panel
    tags:
      - wordpress
```

**Direct array format (JSON):**

```json theme={null}
[
  {
    "name": "Block SQLi in Query",
    "category": "sqli",
    "severity": "critical",
    "action": "block",
    "match_mode": "regex",
    "pattern": "(?i)(union\\s+select|sleep\\s*\\(|benchmark\\s*\\()",
    "targets": ["query", "body"],
    "enabled": true,
    "paranoia": 1
  }
]
```

### Import Behavior

* **IDs are reset** — imported rules receive new IDs; existing rules are not overwritten
* **Host ID is cleared** — all imported rules become global (not host-specific)
* **Defaults applied** — missing fields are normalized:
  * Category defaults to `custom`
  * Severity defaults to `medium`
  * Action defaults to `block`
  * Paranoia defaults to `1`
  * Regex rules with no targets default to `path`, `query`, `body`, `headers`
* **Validation** — each rule is validated through the same logic used by the UI (regex compilation, condition field/operator checks, etc.)
* **Proxy reload** — after import, the proxy manager reloads all rule chains

### Rule Schema Reference

| Field                | Type    | Description                                                              |
| -------------------- | ------- | ------------------------------------------------------------------------ |
| `name`               | string  | Rule display name (required)                                             |
| `description`        | string  | Detailed description                                                     |
| `category`           | string  | Classification (e.g., `sqli`, `xss`, `custom`)                           |
| `severity`           | string  | `low`, `medium`, `high`, or `critical`                                   |
| `action`             | string  | `block`, `allow`, `challenge`, `log`, or `redirect`                      |
| `enabled`            | boolean | Whether the rule is active                                               |
| `paranoia`           | integer | Paranoia level (1-4)                                                     |
| `match_mode`         | string  | `conditions`, `regex`, or `correlated`                                   |
| `correlation_config` | object  | Correlation configuration (for correlated mode — see [Mnemos](./mnemos)) |
| `condition_logic`    | string  | `AND` or `OR` (for condition mode)                                       |
| `conditions`         | array   | List of condition objects (for condition mode)                           |
| `pattern`            | string  | RE2 regex pattern (for regex mode)                                       |
| `targets`            | array   | Request surfaces to inspect (for regex mode)                             |
| `tags`               | array   | Free-form string tags                                                    |
| `owasp_ids`          | array   | Associated OWASP identifiers                                             |
| `cve_ids`            | array   | Associated CVE identifiers                                               |

### Condition Object Schema

| Field            | Type    | Description                    |
| ---------------- | ------- | ------------------------------ |
| `field`          | string  | Request field to inspect       |
| `operator`       | string  | Comparison operator            |
| `value`          | string  | Value to compare against       |
| `case_sensitive` | boolean | Enable case-sensitive matching |
| `negated`        | boolean | Invert the condition result    |

***

## Bundled Rule Sets

Aegis ships with importable rule sets in the `rules/` directory. These can be imported via the admin API or loaded from the CLI.

### PayloadsAllTheThings Rule Set

The `payloads-all-the-things.yaml` rule set provides 35 detection rules derived from the [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings) repository. It covers attack categories beyond the 26 built-in rules, including:

| Category                 | Rules | Coverage                                                                          |
| ------------------------ | ----- | --------------------------------------------------------------------------------- |
| SQL Injection            | 5     | Auth bypass, time-based blind, error-based extraction, polyglots, stacked queries |
| NoSQL Injection          | 2     | MongoDB operator injection, server-side JavaScript injection                      |
| Command Injection        | 3     | Shellshock, newline injection, backtick/subshell execution                        |
| XXE Injection            | 3     | Entity declaration, Billion Laughs, XInclude                                      |
| GraphQL                  | 2     | Introspection probing, batching attacks                                           |
| Server Side Includes     | 2     | SSI directives, Edge Side Includes (ESI)                                          |
| XSLT Injection           | 1     | XSLT code execution and information disclosure                                    |
| File Inclusion           | 2     | Remote file inclusion, PHP wrapper exploitation                                   |
| Open Redirect            | 1     | Parameter-based redirect manipulation                                             |
| Request Smuggling        | 1     | Transfer-Encoding desync                                                          |
| CSV Injection            | 1     | Spreadsheet formula injection                                                     |
| SAML Injection           | 1     | Signature stripping and wrapping                                                  |
| JWT Attacks              | 1     | Algorithm confusion (alg: none, key confusion)                                    |
| Prototype Pollution      | 1     | **proto** and constructor.prototype manipulation                                  |
| Web Cache Deception      | 1     | Static extension appended to dynamic paths                                        |
| HTTP Parameter Pollution | 1     | Duplicate parameter injection                                                     |
| File Upload              | 1     | Dangerous extension and null byte injection                                       |
| LaTeX Injection          | 1     | File read and command execution via LaTeX                                         |
| Prompt Injection         | 1     | LLM instruction override and jailbreak                                            |
| Spring Boot Actuator     | 1     | Exposed management endpoints                                                      |
| CSS Injection            | 1     | Attribute selector exfiltration                                                   |
| Source Code Exposure     | 1     | .git, .svn, .hg directory access                                                  |
| OAuth                    | 1     | Redirect URI manipulation                                                         |
| LDAP (Extended)          | 1     | Blind LDAP and attribute extraction                                               |
| DNS Rebinding            | 1     | Known rebinding service domains                                                   |
| Type Juggling            | 1     | PHP loose comparison bypass                                                       |
| Race Condition           | 1     | Last-byte sync headers                                                            |
| WebSocket                | 1     | Cross-site WebSocket hijacking                                                    |
| IDOR                     | 1     | Sequential ID enumeration patterns                                                |
| Dependency Confusion     | 1     | Internal package name probing                                                     |

The rule set also includes 3 **Mnemos correlation rules** that link reconnaissance and exploitation patterns:

* **Recon to Exploitation Campaign** — introspection/actuator probing followed by active injection
* **Multi-Vector Injection Campaign** — 4+ distinct injection techniques from the same client in 3 minutes
* **Auth Attack Campaign** — JWT, SAML, OAuth, and type juggling attacks correlated within 5 minutes

### Mnemos OOB SQLi and Exfiltration Rule Set

The `mnemos-oob-sqli-and-exfil.yaml` rule set provides detection chains for:

* **Out-of-Band SQL Injection** — OOB function primitives + DNS/UNC exfil, correlated by Mnemos
* **Data Exfiltration Campaigns** — sensitive endpoint access + bulk extraction + schema recon, correlated by Mnemos

### Importing a Rule Set

```bash theme={null}
curl -X POST http://127.0.0.1:9443/api/v1/rules/import \
  -H "Cookie: kwaf_session=<session>" \
  -H "X-CSRF-Token: <token>" \
  -F "file=@rules/payloads-all-the-things.yaml"
```
