# CSPT the Eval Villain Way!

CSPT in a playground app lets attacker-controlled path redirect a client-side GET, whose response feeds an authenticated POST path, yielding CSPT2CSRF.

- Payout: Research
- Program: CSPT playground
- Write-up by: Doyensec
- Disclosed: 2024-12-02
- Write-up quality: 6/10
- Original: https://blog.doyensec.com/2024/12/03/cspt-with-eval-villain.html
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-doyensec-com-2024-12-03-cspt-with-eval-villain-html
- Tags: area:web domain:web impact:integrity kind:research platform:research tech:react technique:chained technique:source-review vuln:csrf vuln:open-redirect vuln:path-traversal

**Target:** Client-side fetch sinks in a React web app (URL path source)
**Root cause:** URL path segment is used unsanitized in a client-side fetch path, and the response's _id field is then used in a second authenticated POST fetch path, allowing traversal and redirect to attacker server.
**Steps:**
1. Enable Eval Villain 'Path search' and refresh; observe fetch calls using the path.
2. Append `%2fasdf%2f..` to the URL path to test traversal normalization.
3. Enable evSourcer global; inject the CSPT fetch response via conditional breakpoint `evSinker(e, 'x', true)` at `ot.seenNote`.
4. Refresh; observe `_id` from response hitting the second fetch sink.
5. Use open redirect on first GET (redirect:follow) to serve attacker JSON with crafted `_id` into the authenticated POST path.
**How found:** Used Eval Villain to hook fetch and detect path-derived sources; tested `%2fasdf%2f..` normalization; read stack trace 'magic zone' transition from minified library to app code to locate fetchNoteById and instrument response into evSourcer.
**Exploitation:** Attacker controls path of client-side GET with redirect:follow; an open redirect sends it to attacker server returning JSON whose _id is used in an authenticated POST fetch path, achieving CSRF-style action.
**Escalation:** Chaining CSPT GET sink with open redirect and secondary POST sink to convert client-side path control into authenticated state-changing request.
**Insight:** When a path-derived fetch response is re-consumed, instrument the response object at the app-code boundary (where minified names become readable) via a conditional breakpoint calling evSinker, then watch for its fields hitting a second sink.

## Proof of concept (copied exactly from the original report)

**CSPT test payload appended to URL path**

```
just add the string %2fasdf%2f.. to the end of the
path. This is a good tip, since this will normalize to the original path
```

**Conditional breakpoint evSinker instrumentation call**

```
Right-click on the line number that contains ot.seenNote and click “Add
Conditional breakpoint”. Add in the evSinker call, using a name you can
recognize as injecting the e variable.
```

