Choose the cookie layer
Imperva can load a Reese84 sensor, the UT.mvc bootstrap, or both. Select the task from the captured script chain, not from the site's brand name.
| Expected cookie | Task type | Captured URL inputs |
|---|---|---|
reese84 |
ImpervaCookie |
Required sensorUrl; optional utmvcUrl and iframeUrl when the page has them |
___utmvc |
ImpervaUtmvcCookie |
Required scriptUrl; optional iframeUrl |
Both tasks require websiteURL, userAgent, your sticky proxy and cookies from the blocked session. Neither task discovers its script URLs by fetching the protected page.
Capture the Reese84 block
Open DevTools, Network, preserve the log and request the page through the proxy that will solve and replay it. From that same block response, capture:
| Field | Capture from |
|---|---|
sensorUrl |
The Reese84 sensor script request; the path is site-specific and a ?s=... query on it is fine |
utmvcUrl |
Optional: the /_Incapsula_Resource?SWJIYLWA=... bootstrap request, only when the page loads one |
iframeUrl |
Optional: the src of iframe#main-iframe, typically /_Incapsula_Resource?CWUDNSAI=...; a "Pardon Our Interruption" page has none |
cookies |
The block response cookies, including incap_ses_* and any visid_incap_* or nlbi_* values |
Resolve relative src paths against websiteURL and preserve the query strings. All URL task fields must be absolute public HTTP(S) URLs. The URLs and session cookies must come from one current block, with the same proxy exit IP and User-Agent.
A session cookie must be visible to the protection script at websiteURL. The API rejects a missing, empty, wrong-domain, wrong-path or HttpOnly-only incap_ses_* cookie before charging. Supplying an unrelated application cookie does not seed the protection session.
Reese84 request
Send this shape to POST /createTask, replacing every example value with the current capture:
{
"clientKey": "sur_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"task": {
"type": "ImpervaCookie",
"websiteURL": "https://example.com/account",
"sensorUrl": "https://example.com/site-specific-sensor.js",
"utmvcUrl": "https://example.com/_Incapsula_Resource?SWJIYLWA=YOUR_CAPTURE",
"iframeUrl": "https://example.com/_Incapsula_Resource?CWUDNSAI=YOUR_CAPTURE",
"cookies": "incap_ses_123=YOUR_SESSION; visid_incap_123=YOUR_VISITOR",
"userAgent": "YOUR_SUPPORTED_USER_AGENT",
"proxy": "http://user:password@proxy.example.com:8080"
}
}
scriptUrl is not a Reese84 input. Send sensorUrl, and utmvcUrl and iframeUrl only when the captured page has them; a missing sensorUrl is rejected before a VM starts.
UTMVC request
For a page that loads only the UT.mvc bootstrap, capture its complete URL as scriptUrl. Include iframeUrl only if that page has the corresponding main iframe:
{
"clientKey": "sur_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"task": {
"type": "ImpervaUtmvcCookie",
"websiteURL": "https://example.com/account",
"scriptUrl": "https://example.com/_Incapsula_Resource?SWJIYLWA=YOUR_CAPTURE",
"cookies": "incap_ses_123=YOUR_SESSION; visid_incap_123=YOUR_VISITOR",
"userAgent": "YOUR_SUPPORTED_USER_AGENT",
"proxy": "http://user:password@proxy.example.com:8080"
}
}
The same session-cookie requirement applies. The Reese84 API reference and UTMVC reference list their separate required fields.
Ready result and replay
Poll POST /getTaskResult with your clientKey and the returned taskId. Both task types return this shape; the cookie name comes from the selected task:
{
"errorId": 0,
"status": "ready",
"solution": {
"reese84": "<reese84-cookie-value>"
}
}
This example is for ImpervaCookie. ImpervaUtmvcCookie returns ___utmvc instead of reese84. Set the named value on the protected site's domain and apply any entries in the optional cookies name-to-value object. Preserve your application's session and repeat the request through the same proxy with the task's userAgent.
A ready credential means the cookie was generated. It does not certify a 200 from the application: a site can still block the IP, require another layer or reject its own session checks. Check an application-specific success marker as well as HTTP status.
Complete solve and replay examples
Fill SENSOR_URL and SESSION_COOKIES for Reese84, plus UTMVC_URL and IFRAME_URL when the captured page has them. The script creates and polls the task, preserves that session and replaces only reese84:
# imperva-python.py - solve Imperva Reese84 and request the protected page with the reese84
# cookie.
# Install: pip install requests
# Run: python imperva-python.py
import time
import requests
# Your SurSolver API key.
CLIENT_KEY = "sur_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# The challenged page, exactly as it shows the challenge.
TARGET_URL = "https://example.com/page"
# The proxy for the solve and the replay: http://user:pass@host:port or socks5://host:port.
PROXY_URL = "http://username:password@proxy.example.com:8080"
# The Reese84 sensor script URL from the current block page.
SENSOR_URL = "https://example.com/sensor.js"
# The SWJIYLWA UT.mvc bootstrap URL, when that same block page loads one.
UTMVC_URL = None
# The CWUDNSAI URL of iframe#main-iframe, when that same block page has one.
IFRAME_URL = None
# Existing session cookies as a Cookie header value (name=value; name2=value2).
SESSION_COOKIES = "incap_ses_123=YOUR_CAPTURE; visid_incap_123=YOUR_CAPTURE"
# The User-Agent the solve runs with; send the result with this same user agent.
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36"
# Text that appears only in a response the site accepted.
SUCCESS_TEXT = "PASTE_ACCEPTED_MARKER"
API = "https://api.sursolver.com"
POLL_ATTEMPTS = 60
def call(path, body):
# API errors are HTTP 200 with errorId 1; anything else is a transport failure.
response = requests.post(f"{API}{path}", json=body, timeout=30)
response.raise_for_status()
data = response.json()
if data["errorId"] != 0:
raise RuntimeError(f'{data["errorCode"]}: {data["errorDescription"]}')
return data
def solve(task):
created = call("/createTask", {"clientKey": CLIENT_KEY, "task": task})
for _ in range(POLL_ATTEMPTS):
result = call("/getTaskResult", {"clientKey": CLIENT_KEY, "taskId": created["taskId"]})
if result["status"] == "ready":
return result["solution"]
time.sleep(3)
raise TimeoutError(f'task {created["taskId"]} was not ready in {POLL_ATTEMPTS} polls')
def without_empty(fields):
# Optional task fields are sent only when they have a value.
return {name: value for name, value in fields.items() if value not in (None, "")}
PROXIES = {"http": PROXY_URL, "https": PROXY_URL}
def main():
solution = solve({
"type": "ImpervaCookie",
"websiteURL": TARGET_URL,
"sensorUrl": SENSOR_URL,
"cookies": SESSION_COOKIES,
"userAgent": USER_AGENT,
**without_empty({
"utmvcUrl": UTMVC_URL,
"iframeUrl": IFRAME_URL,
}),
"proxy": PROXY_URL,
})
# Replay with the user agent the solve ran with, through the same proxy.
headers = {"User-Agent": USER_AGENT}
cookies = dict(part.strip().split("=", 1) for part in (SESSION_COOKIES or "").split(";")
if "=" in part)
cookies["reese84"] = solution["reese84"]
cookies = {
**cookies,
**solution.get("cookies", {}),
"reese84": solution["reese84"],
}
response = requests.get(
TARGET_URL,
headers=headers,
cookies=cookies,
proxies=PROXIES,
timeout=30,
)
if not response.ok or SUCCESS_TEXT not in response.text:
raise SystemExit(f"The site did not accept the result (HTTP {response.status_code}).")
print("The site accepted the result.")
if __name__ == "__main__":
main()
For UTMVC, fill SCRIPT_URL and SESSION_COOKIES; supply IFRAME_URL when the captured page has one. This script replaces only ___utmvc:
# imperva-utmvc-python.py - solve Imperva UTMVC and request the protected page with the ___utmvc
# cookie.
# Install: pip install requests
# Run: python imperva-utmvc-python.py
import time
import requests
# Your SurSolver API key.
CLIENT_KEY = "sur_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# The challenged page, exactly as it shows the challenge.
TARGET_URL = "https://example.com/page"
# The proxy for the solve and the replay: http://user:pass@host:port or socks5://host:port.
PROXY_URL = "http://username:password@proxy.example.com:8080"
# The complete SWJIYLWA UT.mvc bootstrap URL from the current block page.
SCRIPT_URL = "https://example.com/challenge.js"
# The CWUDNSAI main-iframe URL when this page includes one.
IFRAME_URL = None
# Existing session cookies as a Cookie header value (name=value; name2=value2).
SESSION_COOKIES = "incap_ses_123=YOUR_CAPTURE; visid_incap_123=YOUR_CAPTURE"
# The User-Agent the solve runs with; send the result with this same user agent.
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36"
# Text that appears only in a response the site accepted.
SUCCESS_TEXT = "PASTE_ACCEPTED_MARKER"
API = "https://api.sursolver.com"
POLL_ATTEMPTS = 60
def call(path, body):
# API errors are HTTP 200 with errorId 1; anything else is a transport failure.
response = requests.post(f"{API}{path}", json=body, timeout=30)
response.raise_for_status()
data = response.json()
if data["errorId"] != 0:
raise RuntimeError(f'{data["errorCode"]}: {data["errorDescription"]}')
return data
def solve(task):
created = call("/createTask", {"clientKey": CLIENT_KEY, "task": task})
for _ in range(POLL_ATTEMPTS):
result = call("/getTaskResult", {"clientKey": CLIENT_KEY, "taskId": created["taskId"]})
if result["status"] == "ready":
return result["solution"]
time.sleep(3)
raise TimeoutError(f'task {created["taskId"]} was not ready in {POLL_ATTEMPTS} polls')
def without_empty(fields):
# Optional task fields are sent only when they have a value.
return {name: value for name, value in fields.items() if value not in (None, "")}
PROXIES = {"http": PROXY_URL, "https": PROXY_URL}
def main():
solution = solve({
"type": "ImpervaUtmvcCookie",
"websiteURL": TARGET_URL,
"scriptUrl": SCRIPT_URL,
"cookies": SESSION_COOKIES,
"userAgent": USER_AGENT,
**without_empty({
"iframeUrl": IFRAME_URL,
}),
"proxy": PROXY_URL,
})
# Replay with the user agent the solve ran with, through the same proxy.
headers = {"User-Agent": USER_AGENT}
cookies = dict(part.strip().split("=", 1) for part in (SESSION_COOKIES or "").split(";")
if "=" in part)
cookies["___utmvc"] = solution["___utmvc"]
cookies = {
**cookies,
**solution.get("cookies", {}),
"___utmvc": solution["___utmvc"],
}
response = requests.get(
TARGET_URL,
headers=headers,
cookies=cookies,
proxies=PROXIES,
timeout=30,
)
if not response.ok or SUCCESS_TEXT not in response.text:
raise SystemExit(f"The site did not accept the result (HTTP {response.status_code}).")
print("The site accepted the result.")
if __name__ == "__main__":
main()
These scripts take SESSION_COOKIES as a Cookie header string. The API also accepts cookies as NDJSON, preserving their original host, path and visibility fields. If the site uses both layers, carry the first layer's cookies into the second solve and replay instead of replacing the entire session with one value.
Troubleshooting
| Symptom | Check | Correction |
|---|---|---|
Missing sensorUrl |
No sensor script URL was supplied | Capture the Reese84 sensor request from the block page; add the SWJIYLWA bootstrap and CWUDNSAI iframe URLs only if that page has them |
Missing UTMVC scriptUrl |
Discovery was assumed | Supply the captured bootstrap URL |
| Session rejected before charging | No usable incap_ses_* is visible at the page URL |
Capture the block cookies and preserve host, path and HttpOnly metadata |
| Wrong cookie is returned | The two layers were confused | Select the task matching the site's script chain |
| Ready cookie still sees a block | Exit IP, session, another layer or an application policy differs | Replay in the original context and inspect the protected response |
| Application redirects to login | Authentication cookies were lost | Preserve them alongside the solved cookie |
The Imperva integration article explains how to distinguish the two captured script chains.