Middleware

Subashi WAF Middleware

Introduction

Subashi is a lightweight, configurable Web Application Firewall (WAF) middleware for Kipchak. It provides a robust layer of security by filtering incoming HTTP requests based on customisable rules before they reach your application logic.

The name is inspired by the Arabic/Persian word "Subashi" (سوباشي) which means "shield" or "protection", reflecting the purpose of the middleware to protect your API from malicious attacks.

It's actually taken from the Ottoman Turkish word Subaşı (would have been written سوباشي in Ottoman Turkish), which was the title given to the police chief of a city / town in the Ottoman Empire.

Key features include:

  • Access Control: Allow or block traffic based on IP, headers, query parameters, and more.
  • Rate Limiting: Protect your application from abuse with flexible rate-limiting strategies backed by Memcached or file storage.
  • Granular Rules: Define complex conditions using regex, list matching, and numeric comparisons.

Installation

Install the middleware via composer by running:

composer require kipchak/middleware-subashi

Configuration

The configuration in kipchak.subashi.php can be used to configure Subashi:

The configuration is explained below.

Global Settings

These settings control the master switch and default fallback behavior.

  • enabled (bool): Set to true to activate the WAF. If false, requests pass through unchecked.
  • default_action (string): 'allow' or 'block'. Determines what happens if a request matches no rules.
  • blocked_response_code (int): HTTP status code for blocked requests (Default: 403).

Rate Limiting Configuration

Configures the backend storage for rate limiting.

'rate_limiting' => [
    'enabled' => true,
    'default_limit' => 3,       // Requests per window
    'default_window' => 5,      // Window size in seconds
    'store' => 'memcached',     // 'memcached' or 'file'
    'memcached_pool' => 'cache' // Pool name if using memcached
],

Rules Structure

Rules are defined in three specific arrays:

1. Whitelist (whitelist)

Priority: High. If a request matches a whitelist rule, it is allowed immediately, bypassing all subsequent checks (including rate limits).

  • Use case: Trusted internal IPs, Admin API keys.

2. Blacklist (blacklist)

Priority: Medium. Processed after the whitelist. If a request matches a blacklist rule, it is blocked immediately.

  • Use case: Blocking specific User-Agents, malicious IPs, or specific query parameters.

3. Rate Limit Rules (rate_limit_rules)

Priority: Low. Applies specific rate limits based on conditions.

  • Use case: Stricter limits for unauthenticated users, higher limits for paid tiers.

Rule Syntax

Each rule consists of a name, an action (for whitelist/blacklist), and a list of conditions.

Supported Condition Types:

  • header: HTTP headers (e.g., User-Agent).
  • query_param: URL query parameters.
  • ip: Client IP address.
  • method: HTTP verb (GET, POST).
  • path: Request URI path.
  • body: JSON body fields.

Supported Operators:

  • equals, not_equals
  • contains, not_contains
  • regex (Regular Expression)
  • in_list, not_in_list
  • exists, not_exists
  • gt, lt, gte, lte (Numeric comparisons)

Usage

Once configured, Subashi works automatically as middleware.

Basic Workflow

  1. Incoming Request: The middleware intercepts the HTTP request.
  2. Whitelist Check: Is the IP or API key trusted? → Allow.
  3. Blacklist Check: Is the User-Agent malicious? → Block.
  4. Rate Limit Check: Has the user exceeded their limit? → Block.
  5. Default Action: If no rules match → Allow (based on config).

Example: Blocking a Specific Bot

To block a bot named "BadBot", add this to your blacklist array in the config:

[
    'name' => 'Block BadBot',
    'conditions' => [
        [
            'type' => 'header',
            'key' => 'User-Agent',
            'operator' => 'contains',
            'value' => 'BadBot',
        ],
    ],
    'action' => 'block',
    // Optional to override the default response code:
    'response_code' => 401,
    // Optional to override the default response message:
    'response_message' => 'Unauthorized',
],

Example: Whitelisting an IP

To ensure your office IP is never blocked or rate-limited:

[
    'name' => 'Office IP',
    'conditions' => [
        [
            'type' => 'ip',
            'operator' => 'equals',
            'values' => ['203.0.113.50'],
        ],
    ],
    'action' => 'allow',
],

Git Repository

The source code for this driver is available on 1x.ax at https://1x.ax/mamluk/kipchak/middlewares/subashi.

Previous
Object Storage (S3)