Skip to main content

README.md

# Tiny Robots WAF

[![CI](https://github.com/tinyrbtz/waf/actions/workflows/ci.yml/badge.svg)](https://github.com/tinyrbtz/waf/actions/workflows/ci.yml)
[![Hex version](https://img.shields.io/hexpm/v/rbtz_waf.svg "Hex version")](https://hex.pm/packages/rbtz_waf)
[![Hex downloads](https://img.shields.io/hexpm/dt/rbtz_waf.svg "Hex downloads")](https://hex.pm/packages/rbtz_waf)
[![License](http://img.shields.io/:license-mit-blue.svg)](http://doge.mit-license.org)

A minimal web application firewall plug used by [Tiny Robots](https://github.com/tinyrbtz) apps. It halts vulnerability-scanner requests with a plain `404 Not Found` before they reach the Phoenix router, so probes like `/.env` and `/wp-login.php` never hit session/parser plugs, never raise `Phoenix.Router.NoRouteError`, and never create error-reporting noise.

## What it blocks

- Path segments that are not valid UTF-8 or contain a null byte
- Dot segments such as `/.env`, `/.git/config`, `/foo/.env` — `/.well-known/*` is allowed
- Segments with extensions an Elixir app never serves: `.php`, `.php5`, `.php7`, `.phtml`, `.asp`, `.aspx`, `.jsp`, `.jspx`, `.cgi`
- Paths whose first segment is `wp-*`, `wordpress`, `phpmyadmin`, or `cgi-bin` (case-insensitive)

It is deliberately stateless: no IP tracking, no rate limiting, no logging. Blocked requests are simply answered early and cheaply.

## Installation

```elixir
def deps do
  [
    {:rbtz_waf, "~> 0.1"}
  ]
end
```

## Usage

Put the plug early in your endpoint, before `Plug.Parsers` and `Plug.Session`:

```elixir
defmodule MyAppWeb.Endpoint do
  use Phoenix.Endpoint, otp_app: :my_app

  # ...
  plug Plug.RequestId
  plug Rbtz.WAF
  # ...
  plug MyAppWeb.Router
end
```

### Options

- `:allow_prefixes` — first path segments exempt from the scanner rules, for routes that legitimately serve arbitrary external paths (the encoding rules still apply):

```elixir
plug Rbtz.WAF, allow_prefixes: ["proxy"]
```

## License

MIT — see [LICENSE](LICENSE).