Radware serves its captcha as a plain HTTP 200 from its own host, reached
by a 302 off the protected origin, so a block was indistinguishable from
success and callers rendered the interstitial as content.
That 302 sets the __uzm* family on the origin, and those cookies are the
whole clearance: replaying the original URL returns real content with no
JS and no CAPTCHA solve. Detection covers both shapes - the captcha body,
and the fronting redirect that a follow_redirects=False caller sees
instead, which clears without ever contacting Radware's host.
Detection requires a sensor marker AND a captcha-template marker
together. Radware's sensor and its __uzm* cookies ride on ordinary pages
of a protected site - measured across four tenants - so keying on either
alone would re-flag every page the site serves and spin the retry loop.
Three things the retry loop has to get right, since the interstitial
lives off-origin:
- Rewind to the caller's request before anything reads that state, so
a declined solve rotates against the origin and the raised error
names the caller's URL rather than the captcha page.
- Restore method, body and headers on rewind. Following a 3xx
downgrades POST to GET and drops the body per RFC, which is right
for a real redirect and wrong here; without this a challenged POST
came back as a bodyless GET and still returned 200. The hop to
Radware keeps the RFC behaviour, so bodies and Authorization
headers are never disclosed to it.
- Only claim a solve on clearance that is present, in scope, and
different from what the last attempt replayed with. An unchanged
reissue cannot produce a different answer.
Fixtures are the live gojobs captcha page and its real job page, the
latter included precisely because it is the false positive worth
guarding against. Both are scrubbed: Radware encodes the client IP into
__uzdbm_2 as base64 of "<uuid>$<ip>", so a verbatim capture would
publish it.