Imperva's reese84 cookie: what it is, why it dies, and how to reuse it
Most write-ups about Imperva (Incapsula) stop at "you need the reese84 cookie". That is the easy half. The hard half is that a reese84 value you obtained five minutes ago, from a different IP, will usually be rejected on
Most write-ups about Imperva (Incapsula) stop at "you need the reese84 cookie". That is the easy half. The hard half is that a reese84 value you obtained five minutes ago, from a different IP, will usually be rejected on the first request β and the error you get back does not tell you why.
This is a field note on what the cookie actually contains, why replay fails, and what a working solve-and-reuse loop looks like.
What the cookie is
reese84 is a browser-integrity cookie. It is issued by Imperva's client-side script only after that script has decided the visitor is plausibly human, and it is set on the response that follows a successful challenge. Until you have it, every request to a protected URL returns either the interstitial challenge page or a flat 403.
Structurally, the value is colon-separated in three parts:
- a version prefix,
- a long encoded payload of environment and browser signals collected by the challenge script,
- a signature that binds the payload to the request that produced it.
The middle part is not a bearer token. It is evidence about a specific session, and Imperva re-scores that evidence on every request rather than trusting it once issued.
Why a reese84 from another session fails
Three things get checked against the cookie on replay:
1. IP address. A cookie minted on one IP and replayed from another is re-scored, often into a challenge. This is the single most common cause of "it worked in the solver, it failed in my scraper".
2. HTTP and TLS fingerprint. Header order, HTTP/2 SETTINGS frames, and the TLS ClientHello are compared against what the script observed. A solve performed in a real Chrome and a replay performed by python-requests are two different fingerprints, and the cookie carries a memory of the first one.
3. The paired values from the same run. The cookie, the user agent, and the proxy have to come from one solving session. Pair a fresh cookie with a stale user agent string and the mismatch is itself a signal.
Which is why the reflex of rotating proxies per request makes things worse: each new IP invalidates the cookie you just paid for, you get sent back to the challenge, you solve again, and the loop never converges. Solve on the IP you intend to scrape from, keep that IP for the session, and let the cookie do its job.
The two Imperva modes, and the field mix-up that breaks half of all attempts
Most solving APIs expose Imperva as one task type with two modes. Both are the same type, selected by a flag β and they take different script fields. Getting this wrong is the most common silent failure:
| Mode | Required fields | Notes |
|---|---|---|
| Reese84 |
websiteURL, reeseScriptUrl
|
omit isUtmvc, or set it to false
|
| UT.mvc |
websiteURL, isUtmvc: true, scriptURL
|
scriptURL is the full /_Incapsula_Resource?SWJIYLWA=... URL |
Both accept optional proxy, useragent, language, and preset cookies (each item only name and value). Use a desktop Chrome/Chromium or Android Chrome user agent β Firefox, Edge, Opera, and iOS browsers are unsupported, and an unsupported family shows up as a failed task rather than a validation error.
A minimal Reese84 request:
curl -sS -X POST 'https://www.tiam.codes/v1/tasks' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: reese84-0001' \
--data-binary @- <<'JSON'
{
"type": "imperva",
"task": {
"websiteURL": "https://example.com/protected",
"reeseScriptUrl": "https://example.com/challenge/reese.js",
"proxy": "http://user:[email protected]:8080",
"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
}
}
JSON
Poll GET /v1/tasks/{taskId} until the status is completed, then read cookies (including reese84) and useragent out of the result.
Two lifecycle details worth knowing before you build retries:
-
failedandcancelledare terminal and refunded. -
uncertainis not final. Keep polling the same task id. Creating a new task because the status was ambiguous is how you pay twice for one solve.
Reusing the cookie
Send the cookie with the same proxy and the same user agent that produced it, as one consistent identity per session:
import requests
s = requests.Session()
s.proxies = {"http": PROXY, "https": PROXY}
s.headers.update({
"User-Agent": RESULT_USERAGENT,
"Cookie": f"reese84={RESULT_REESE84}",
})
r = s.get("https://example.com/protected")
Two rules that hold up in practice:
- One identity per session. Cookie + proxy + user agent travel together for the whole session, not per request.
- Reuse, do not re-solve. Re-solving per request costs a task each time and resets the trust the previous solve earned. Batch your work under one session while the cookie is warm.
Troubleshooting, by symptom
| Symptom | Likely cause |
|---|---|
| Challenge page again on the very first request | Wrong mode β UT.mvc site solved as Reese84, or a stale reeseScriptUrl
|
| Works from the solving API's IP, fails from yours | Cookie replayed from a different IP than the solve |
| 403 with a cookie that looks valid | TLS/HTTP fingerprint mismatch β your client library, not the cookie |
Task returns failed
|
Unsupported user agent family, or the script URL no longer exists on the target |
| Intermittent success, no pattern | Session identity is leaking β one of the three values is rotating |
A note on scope
Everything above assumes you have permission to test the target: your own site, a client's site under contract, or a target whose terms allow automated access. Integrity cookies exist to tell humans from bots, so reusing one against a site you do not own is the thing the cookie is designed to stop, and it is usually a terms-of-service problem rather than an engineering one. The interesting engineering is on the authorized side, where you want to verify that your own protection actually discriminates β and for that you need a reliable way to produce a solver-side session, not a way to bypass someone else's.
I work on SolveHub, which is the API used in the examples above; the field tables and error codes are documented there. The diagnosis in this post β IP binding, fingerprint mismatch, mode confusion β applies to any Imperva solver you evaluate, including a self-hosted one.
If you are debugging a reese84 failure right now, the fastest split is: does the same cookie work on the same IP? If yes, it is your client fingerprint. If no, it is the solve.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.