# Stored self-XSS in mercantile.wordpress.org checkout

Stored client-side template injection in mercantile.wordpress.org checkout: billing/shipping address fields rendered as Angular expressions, executing {{1+1}} as 2.

- Payout: hidden
- Severity: low
- Program: WordPress
- Found by: eidelweiss
- Disclosed: 2017-07-14
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/230232
- Library page: https://bugbountylibrary.com/r/h1%3A230232
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:low technique:second-order vuln:xss

**Target:** WooCommerce checkout / my-account address forms on mercantile.wordpress.org
**Root cause:** User-supplied billing/shipping address fields are rendered into the checkout page inside an AngularJS template context without sanitization, so Angular evaluates {{...}} expressions.
**Steps:**
1. Sign up at `https://mercantile.wordpress.org` and log in.
2. Go to `https://mercantile.wordpress.org/my-account/edit-account/` and fill first/last name.
3. Go to `https://mercantile.wordpress.org/my-account/edit-address/`.
4. Fill all Billing Address fields with `{{1+1}}` (except zip) and all Shipping Address fields with `{{1==1}}`, then save.
5. Add any product and proceed to `https://mercantile.wordpress.org/checkout/`.
6. Observe `{{1+1}}` renders as `2` and `{{1==1}}` renders as `true`, confirming template evaluation.
**How found:** Read prior report #221893 which mentioned `ng-bindable`, hypothesized the site uses AngularJS templating, and tested whether address fields are evaluated as Angular expressions at checkout.
**Exploitation:** Stored payload in address fields is evaluated by AngularJS on the checkout page; the report demonstrates arithmetic evaluation ({{1+1}} -> 2) rather than full script execution, but the same context permits Angular expression-based XSS.
**Insight:** When a prior report leaks a framework hint like `ng-bindable`, test every user-controlled field that gets re-rendered on other pages (addresses, names) for Angular `{{ }}` evaluation at checkout/cart, not just the originally reported endpoint.

