.claude/skills/imperva-waf-bypass/SKILL.md
Fix for Python requests returning 500 "Internal Server Error" when calling APIs protected by Imperva/Incapsula WAF, while the same request works with curl. Use when: (1) API call works with curl but fails with Python requests, (2) response headers contain "X-CDN: Imperva" or Incapsula cookies, (3) API returns 500 with no JSON body, just "Internal Server Error" plain text, (4) response contains Set-Cookie with visid_incap_ or nlbi_ prefixes. Solves bot detection issues with Imperva-protected APIs like Resy, and other services using Imperva/Incapsula CDN.
npx skillsauth add Dbochman/dotfiles imperva-waf-python-requestsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Python requests library calls to an API return 500 Internal Server Error with
a plain text body, while the identical request via curl succeeds with 200. The
API is behind Imperva/Incapsula WAF which performs bot detection based on request
headers and TLS fingerprinting.
curl but returns 500 with Python requestsX-CDN: Impervavisid_incap_, nlbi_, or incap_ses_ prefixesAdd browser-like headers to your requests session:
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
"Accept": "application/json, text/plain, */*",
"Origin": "https://example.com", # The web app's origin
"Referer": "https://example.com/", # The web app's URL
}
The critical headers are:
python-requests/2.x by default which Imperva blocks.Origin and Referer may also be required depending on the API's CORS/WAF rules.
X-CDN: Imperva header is still present (confirms you're going through the same path)Before (blocked):
resp = requests.post("https://api.resy.com/3/auth/password",
headers={"Authorization": 'ResyAPI api_key="..."'},
data={"email": "[email protected]", "password": "pass"},
)
# resp.status_code == 500
# resp.text == "Internal Server Error"
After (works):
resp = requests.post("https://api.resy.com/3/auth/password",
headers={
"Authorization": 'ResyAPI api_key="..."',
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
"Accept": "application/json, text/plain, */*",
"Origin": "https://resy.com",
"Referer": "https://resy.com/",
},
data={"email": "[email protected]", "password": "pass"},
)
# resp.status_code == 200
# resp.json() == {"token": "...", ...}
curl works because it sends a different TLS fingerprint and default headers that Imperva doesn't flagtools
Use exact configured Reolink cameras through the local Home Hub for availability and power status, fresh stills, visual commentary, protected Dylan/Julia/household sharing, and reversible spotlight control. Supports trusted owner tasks and explicitly scoped proactive automations; not for Nest or Ring cameras, arbitrary recipients, recordings, account changes, or raw camera APIs.
data-ai
Privately manage Dylan and Julia's household plant inventory and care history by physical location, bed, and exact Flower Cam view. Use for confirmed plant onboarding from camera conversations, camera- or bed-filtered inventory, record corrections, individual or whole-bed care, and private filtered exports. Pair with reolink-camera when an owner asks about plants visible in Flower Cam images.
testing
Inspect and control the physically secured Reachy Mini at Crosstown through ClawBody. Use for requests to check Reachy, look around, express an emotion, play any official emotion or dance preset, speak proactively, mute or unmute its microphone, stop movement, or describe what its camera sees.
tools
Handle Reachy/iMessage handoffs, selective durable memory, forgetting, and diagnostics; automatic context comes from the gateway plugin.