# woocommerce - prevent_caching() bug / bypass

WooCommerce prevent_caching() matched raw REQUEST_URI, so /+cart/ bypassed no-cache headers, enabling cache deception of cart/checkout pages.

- Payout: hidden
- Severity: medium
- Program: Automattic
- Found by: b258ea62bf297b02afa9854
- Disclosed: 2017-09-16
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/241323
- Library page: https://bugbountylibrary.com/r/h1%3A241323
- Tags: area:web domain:web impact:data-leak kind:bounty platform:hackerone sev:medium tech:php tech:wordpress technique:source-review vuln:cache-deception vuln:misconfiguration

**Target:** WordPress/WooCommerce cart, my-account, checkout pages behind caching proxy
**Root cause:** prevent_caching() uses stristr on raw $_SERVER['REQUEST_URI'] to match protected paths, but WordPress canonical redirect accepts '+', '-', '.' variants that don't match the needle, so caching constants/headers are never set.
**Steps:**
1. Visit `https://woocommerce.com/+cart/` (also `-cart/`, `.cart/`) as guest.
2. Observe response lacks no-cache headers and returns `x-cache:pass` with cart cookies set.
3. The needle `/cart/` fails to match `/+cart/` in stristr, so prevent_caching() returns false.
4. With a caching plugin/proxy configured to cache pages, the dynamic cart page gets cached and served to other users.
**How found:** Noticed missing caching headers on odd URL variants, then read class-wc-cache-helper.php and traced how WordPress sanitize_title_with_dashes and redirect_canonical handle '+', '-', '.' characters, realizing the raw REQUEST_URI needle wouldn't match.
**Exploitation:** Attacker lures a victim to a crafted URL like /+my-account/ so the victim's authenticated page is cached by the proxy; attacker then requests the same URL to retrieve the victim's cached account/cart data (cache deception).
**Insight:** When a security check string-matches raw REQUEST_URI, enumerate characters WordPress canonicalization tolerates ('+', '-', '.', trailing slashes) to find variants that reach the same handler but fail the match.

