HexShield HexShield HEXSHIELD

Custom WAF rules that never lock out a real user

Match on path, User-Agent, header or query, then choose allow, challenge, rate-limit or block — with one guardrail the engine enforces at save time: no rule can block every visitor.

Country and IP blocking are blunt instruments. They are the right tool when a whole region or a single address is the problem, and the wrong tool the moment you need to say something more specific: this path, from clients that look like this, should be slowed down — but never my real customers.

Custom rules are that scalpel. Each rule has one to four conditions (all of them must hold) and one action, evaluated per request at the edge, before the request reaches your origin.

What a rule can match

Every condition inspects one field of the incoming request:

  • path — the request URI, e.g. /wp-login.php or /api/
  • method — GET, POST, and so on
  • user_agent — the client's User-Agent string
  • header — any named request header
  • query — the query string
  • country, asn, ip — where the visitor connects from: a country code, a network (ASN) or an address list
  • tls_fp, bot_score — the client's TLS fingerprint and the edge's automation score

The operator decides how the value is compared: equals, prefix, contains or regex, each with a negated form (not_equals, not_regex, …), plus in / not_in for country, ASN and IP lists. A regex is compiled once and length-capped; a pattern that does not compile is rejected when you save, not at request time, so a typo can never take a rule offline mid-attack.

Four actions, in order of force

  • allow — let the request through, skipping later rules. This is how you carve out an exception: "this partner's IP range is always fine."
  • challenge — show the proof-of-work screen. A real browser passes it without the visitor doing anything; a flood tool pays a cost it cannot afford.
  • ratelimit — allow up to N requests per window from one address, then challenge the rest. Good for an endpoint that should be used, just not hammered.
  • block — return 403. The heaviest action, and the one to reach for last.

First match wins

Rules are evaluated top to bottom and the first one that matches decides the request. Order is therefore part of the rule, not an afterthought: put your allow carve-outs above the block that would otherwise catch them. A rule that allows your monitoring probe has to sit above the rule that rate-limits /health, or the probe gets rate-limited too.

The guardrail: no rule can block everyone

Here is the part that matters most, and the reason this engine is safe to hand to a site owner at 3 a.m. during an attack.

A rule whose match would apply to every request cannot block or challenge. If you try to save a rule that matches path contains / or user_agent contains "" with a block or challenge action, the save is refused. Not softened, not logged-and-allowed — refused, before it is ever live.

The reasoning is rule number one of the whole product: a real visitor must never be permanently locked out. A catch-all block is the fastest way to take your own site down, and an attacker who tricks you into writing one has won without sending a single packet. The engine simply does not let that rule exist. A catch-all allow is refused for the mirror-image reason: a rule that waves everything through is almost always a mistake that disables the protection behind it.

The check also runs on your rules together: two narrow rules whose combination covers every request (for example path starts with /a and path does not start with /a) are refused as well, and so is blocking everyone outside a country or address list unless the rule also names a path. What no check can know is your own intent, so try an IP- or country-based rule from your own network (IPv6 included) before you rely on it.

Beyond custom rules: three switches

Some patterns are common enough that they ship as toggles rather than rules you have to write:

  • Honeypot paths — list paths that no real visitor should ever request (a fake /wp-admin on a site that does not run WordPress). A client that fetches one has told you what it is.
  • Hosting-ASN challenge — challenge traffic originating from datacenter and hosting networks. Real users browse from homes and phones; a request from a server farm is not automatically bad, but it is worth a quick proof-of-work.
  • Empty / known-tool User-Agent challenge — challenge requests with no User-Agent or one that names a scripting tool. These never hard-block, because a mislabeled client is still possibly a person.

Every one of these is per-site and takes effect without a redeploy. You can tighten a rule while an attack is landing and loosen it the moment it passes — which is exactly when you find out whether your rules respect rule number one.

Put your site behind the shield today

Nothing to install. Point your DNS at the HexShield edge, keep your origin IP out of sight, and filter attacks before they reach your server.