What You'll Build
In this hands-on lab you will run OWASP Juice Shop, a deliberately vulnerable web application built for security training, and use it to find and exploit real broken-access-control flaws in a safe, legal environment. You will confirm an IDOR, attempt a vertical privilege escalation, and then reason about the server-side fix each flaw requires.
The goal is not merely to break things but to connect the theory from Module 1 to observable behaviour. By watching an id change leak another user's data, and by seeing a hidden admin route respond to a direct call, you will internalise why authorisation must be re-verified on the server for every request. You will finish by writing the remediation you would ship.
Prerequisites
- Docker installed, or Node.js 18+ if you prefer running Juice Shop directly from source.
- A modern browser with developer tools, since you will inspect and modify requests.
- Completion of the Module 1 readings on broken access control and IDOR, whose concepts this lab exercises directly.
- An understanding that you must only ever test applications you own or are explicitly authorised to test, such as Juice Shop locally.
Setup & Project Structure
Run Juice Shop locally in a container so it is isolated and disposable. The application starts on port 3000 and ships with a catalogue, user accounts, and an admin area, all intentionally flawed. Keep your browser's developer tools open on the Network tab throughout, because the exercise is about observing and altering the requests the site makes rather than only clicking the interface.
# Run OWASP Juice Shop locally in Docker (isolated, disposable)
docker run --rm -p 3000:3000 bkimminich/juice-shop
# Then open the app and its developer tools:
# http://localhost:3000 (the application)
# F12 -> Network tab (watch every request/response)
# Register two separate accounts so you have your own data
# plus a 'victim' account whose data you will try to reach.Step 1 — Foundation: Establish a Baseline
First, register two accounts, then log in as the first and browse to something tied to your identity, such as your basket or a saved address. Watch the Network tab and note the exact request the browser sends, including the endpoint and any numeric identifier in the URL or JSON body. This captured request is your baseline: the legitimate call whose identifier you will later tamper with.
# Example of a captured baseline request (your ids will differ)
GET /rest/basket/6 HTTP/1.1
Host: localhost:3000
Authorization: Bearer <your-jwt>
# Note the object id in the path (here, basket 6).
# This is the identifier you will change in the next step.Step 2 — Core Logic: Confirm the IDOR
Now change the identifier in your captured request to a neighbouring value and replay it, either by editing and resending from the developer tools or with a command-line tool. If the server returns another user's basket rather than an error, you have confirmed an IDOR: the endpoint acted on the id without verifying you own that basket. Record the request, the response, and exactly what data leaked.
# Replay the baseline with a DIFFERENT id (ownership test)
curl -s http://localhost:3000/rest/basket/7 \
-H "Authorization: Bearer <your-jwt>"
# If this returns basket 7's contents (not yours, not a 403/404),
# the endpoint is vulnerable: it never checked that you own basket 7.
# Document: request sent, status code, and the leaked fields.Step 3 — Integration & Enhancement: Attempt Vertical Escalation
Next, probe for privilege escalation. Look for an administration route that the normal interface never links to for your account, then request it directly as your logged-in non-admin user. If the server responds with admin data instead of denying you, that is vertical escalation: a higher-privilege endpoint that was hidden in the UI but never protected on the server. Combine this finding with your IDOR to map the full access-control picture.
# Request an admin-only route directly as a NON-admin user
curl -s http://localhost:3000/rest/admin/application-configuration \
-H "Authorization: Bearer <your-non-admin-jwt>"
# If admin data returns instead of 403 Forbidden, the endpoint
# relied on the UI hiding it — a vertical privilege escalation.
# Note: exact admin paths vary by Juice Shop version; explore
# the Network tab and the app's own JavaScript for candidates.Step 4 — Testing & Verification: Write the Fix
Finally, turn attacker into defender. For each confirmed flaw, write the server-side control that would close it: scope the basket lookup to the authenticated user so a mismatched id returns 404, and add an authorisation check to the admin route so non-admins receive 403. Verify your reasoning by describing the request that previously succeeded and explaining precisely why the fixed server would now reject it.
// Remediation for the IDOR: bind the lookup to the caller
app.get('/rest/basket/:id', requireLogin, async (req, res) => {
const basket = await db.baskets.findOne({
id: req.params.id,
userId: req.user.id // ownership enforced server-side
});
if (!basket) return res.status(404).end(); // don't confirm existence
res.json(basket);
});
// Remediation for the admin route: explicit role check
app.get('/rest/admin/*', requireLogin, (req, res, next) => {
if (!req.user.roles.includes('admin')) return res.status(403).end();
next(); // vertical escalation blocked
});Warning: Only ever run these techniques against Juice Shop or another system you own or are explicitly authorised to test. Sending tampered requests to applications you do not have written permission to test is illegal in most jurisdictions, regardless of intent. Keep the container local, and never point these tools at a third party's live site.
Extension Challenge: Deepen the lab with three additions. Use the JWT you captured to inspect its payload and consider what an unverified 'none' algorithm token would let you forge, previewing Module 3's JWT lesson. Enumerate several basket ids and quantify how many users you could reach. Finally, write an automated test, in the style of Lesson 1, that logs in as one user and asserts a 404 when requesting another user's basket, so the fix stays enforced.
- OWASP Juice Shop is a deliberately vulnerable app that provides a safe, legal environment to practise finding and exploiting access-control flaws.
- Establishing a baseline of normal request behaviour first is what makes the effect of tampering with an identifier observable and clear.
- Confirming an IDOR means changing a single object identifier and seeing the server return another user's data instead of denying the request.
- Vertical privilege escalation is reaching an admin route directly that the interface merely hid, proving that hiding is not securing.
- Every confirmed flaw maps to a concrete server-side fix: scope lookups to the authenticated user and add explicit role checks that fail closed.
- You must only test systems you own or are explicitly authorised to test; running these techniques against others is illegal regardless of intent.