Docs/Wire contract (v1)

WAF-safe encoding

A global security middleware inspects every query string for SQL-injection-shaped substrings — substrings that occur constantly in ordinary URLs and keywords. Encode wrong, and real traffic gets 403'd.

The filter

The backend applies a global WAF middleware (SqlInjectionMiddleware) that lowercases the entire raw query string and returns 403 {"error": "Request blocked due to security policy"} if it contains any of these as a bare substring:

text
--  ;--  /*  */  @@  @  char  nchar  varchar  nvarchar  alter  begin  cast  create
cursor  declare  delete  drop  end  exec  execute  fetch  insert  kill  open  select
sys  sysobjects  syscolumns  table  update  union  waitfor  xp_  sp_
' or '1'='1   ' or 1=1   1=1   or 1=1

These substrings are everywhere in real content

Look closely: end, open, cast, sys, char, table, @, select, update, union appear constantly inside real URLs and keywords — weekend, broadcast, timetable, /opensource, user@, /select-plan, /updates. Sending page_url/page_keywords/us_privacy/euconsent_v2 with ordinary URL-encoding will therefore randomly 403 in production — the failure rate tracks exactly how common these substrings are in your traffic's real URLs.

The rule

For the four free-text/base64 params (page_url, page_keywords, us_privacy, euconsent_v2), every SDK percent-encodes every byte of the value as %XX (uppercase hex, UTF-8). The raw query then contains only %, hex digits, &, = and the (safe) param names — so no keyword substring can ever survive — while the server still percent-decodes back to the true value for the handler.

Ordinary encoding vs. byte-safe encoding

text
page_url = "https://example.com/weekend-sale?ref=open"

# Ordinary encodeURIComponent — SURVIVES the substrings "end" and "open":
page_url=https%3A%2F%2Fexample.com%2Fweekend-sale%3Fref%3Dopen
                                      ^^^ "end" and "open" still readable -> 403

# Byte-percent-encode every byte instead — no keyword substring can survive:
page_url=%68%74%74%70%73%3A%2F%2F%65%78%61%6D%70%6C%65%2E%63%6F%6D%2F%77%65%65%6B%65%6E%64%2D%73%61%6C%65%3F%72%65%66%3D%6F%70%65%6E

api_key, slot_id and slot_name use ordinary URL-encoding — their charset (pk_…, UUIDs, publisher-chosen slugs) cannot contain a blocked keyword in practice. Full-encoding them too is harmless, and some SDKs do so defensively.

How this is verified

Every SDK ships a test that reconstructs the exact SQL_KEYWORDS list above and asserts the lowercased raw query it produces for a deliberately nasty page_url contains none of them — including an end-to-end test against a local mock server that reproduces the backend WAF. If you're building a custom client against the raw contract instead of an SDK, port that test first.