Skip to main content

uri-blocker

uri-blocker

Blocks requests whose request URI matches any configured block_rules regex. Matching requests receive a configurable status (default 403) through the node's denied port. Place it at the front of the pipeline, before auth and upstream nodes.

Configuration

block_rules is required and must be non-empty; regexes are compiled at config load, so an invalid pattern fails fast.

KeyTypeDefaultDescription
block_rulesarray of regex stringsrequiredRules tested against the request URI. A request matching any rule is rejected.
rejected_codeinteger (200–599)403HTTP status for rejections.
rejected_msgstringWhen set, rejections carry a JSON body {"error_msg": ...}; when unset the body is empty.
case_insensitiveboolfalseMatch rules case-insensitively (each rule is compiled with (?i)).
type: uri-blocker
config:
block_rules: ["root.exe", "root.m+", "^/admin/"]
rejected_code: 404
case_insensitive: true

Matching

The subject is the request path plus ?query when query parameters exist, so a rule can hit either the path (^/admin/) or a query value (root.exe against /download?file=root.exe). Matching is unanchored Rust regex syntax; anchor with ^/$ where needed.

Behavior

A blocked request writes rejected_code onto context.response — with a JSON body {"error_msg": rejected_msg} (content-type: application/json) when rejected_msg is set, otherwise an empty body — and exits through the denied port. Non-matching requests pass through the success port untouched; the plugin does not write to context.message.

Behavior notes

featherbit compiles each rule separately and tests them in order, giving clear per-rule config errors. The query string is rebuilt from parsed parameters (sorted key=value pairs) rather than the raw wire bytes, and patterns use Rust regex syntax, not PCRE.

Ports

uri-blocker declares three output ports: success, denied (a rejection is prepared), and error (never actually used — the plugin never fails). Like success, denied is a mandatory port: the policy compiler rejects any policy that leaves it unwired. Wire uri-blocker.denied straight to client so the prepared rejection reaches the caller instead of continuing into upstream:

edges:
- from: uri-blocker.success
to: upstream.in
- from: uri-blocker.denied
to: client.in

Errors

This node never fails at execution time: it always returns through success, so its error port is never taken.