Web Application Security for Beginners · lesson 1 · 2026-08-23 · updated 2026-10-12
Broken Access Control & IDOR — Web Application Security for Beginners
Before you start
- OWASP Juice Shop (a deliberately vulnerable practice app) from the
bkimminich/juice-shopDocker image, bound to 127.0.0.1:3000. - A demo user registered in Juice Shop (the lesson logs in as
demo@ehq.local/Exploit-HQ-123; register any user and use your own email and password); the lesson logs in and saves its token totoken.txtin your working folder. curlandjq(both preinstalled on Kali).- Only test systems you own or are authorized to test.
Welcome to The Exploit HQ, and to a brand new beginner series on web application vulnerabilities. This is part one, and you need zero experience to follow along.
Today we learn the flaw that currently sits at number one on the industry’s list of web weaknesses, the O-WASP Top Ten. It is called broken access control, and the idea is simple enough for anyone to follow.
First, the words. Access control is just the set of rules that decides who is allowed to see or do what.
What is access control?
- The rules for who may see or do what
- Your password. The lock on a changing room.
- Broken = you reach things that were never yours
Your password is access control. The lock on a changing room is access control. It keeps your things yours. When it is broken, those rules do not really stop you, and you can reach things that were never meant to be yours.
Here is the exact trick we will see today, drawn out.
You log in as yourself. Then you ask the app for some data using a number, like basket number one. If the app forgets to check that the basket is really yours, it just hands it over.
So you change the one to a two, and you get user two’s basket. Change it to a three, and you get user three’s. That is the whole flaw.
Now picture that number pointing at something other than a shopping basket.
Why should you care?
- Swap the basket for a bank statement
- …or a medical record, or a private message
- Same bug becomes a real data breach
- It’s #1 on the OWASP Top 10
A bank statement. A medical record. A private message. The same simple bug, but now a serious data breach. That is why this sits at the very top of the O-WASP Top Ten, and why real companies still get hit by it.
We only need the terminal and three simple ideas.
The tools we’ll use
- curl — sends a web request from the terminal
- a token — a secret code that proves you’re logged in
- jq — prints the app’s reply so it’s readable
curl is a small program that sends a web request from the terminal. Think of it as a browser with no window. A token is a long secret code the app gives you when you log in, to prove who you are. And jq is a tiny helper that takes the app’s reply and prints it neatly, so a human can read it.
Let’s break down our very first command before we run it, piece by piece.
Step 1 — log in and save our token
curl -s .../rest/user/login -H "Content-Type: application/json" -d '{"email":"…","password":"…"}' | jq -r .authentication.token > token.txt
| Part | What it does |
|---|---|
curl -s |
send a web request quietly, with no progress bar |
.../rest/user/login |
the app’s login door — where we send our details |
-H "Content-Type: json" |
tell the app we’re sending data as JSON, a simple text format |
-d '{email,password}' |
the data we send: our email and our password |
| jq -r .…token |
from the app’s reply, pull out just the token |
> token.txt |
save that token into a file so we can reuse it later |
In plain terms: we hand the app our email and password, it hands us back a token, and we tuck that token into a file. Now let’s actually open the terminal and type it together.
Type it with me, slowly.
curl -s http://127.0.0.1:3000/rest/user/login -H "Content-Type: application/json" -d '{"email":"demo@ehq.local","password":"Exploit-HQ-123"}' | jq -r .authentication.token > token.txt
Notice nothing printed, and that is exactly right, because we sent the token straight into our file, token dot txt. Think of that file as a wristband from the door. Show the wristband, and the app lets us back in without logging in again.
Now the important command. Let’s break this one down too.
Step 2 — read a basket (then change the number)
curl -s -H "Authorization: Bearer $(cat token.txt)" http://127.0.0.1:3000/rest/basket/1 | jq '{basket, owner_user, items}'
| Part | What it does |
|---|---|
curl -s |
send a web request quietly |
-H "Authorization: Bearer …" |
attach our login token, so the app knows we’re logged in |
$(cat token.txt) |
read our saved token back out of the file |
/rest/basket/1 |
ask for basket number 1 — THIS is the number we’ll change |
| jq '{…}' |
tidy the reply and show the basket, its owner, and the items |
So we prove we are logged in with our token, we ask for basket number one, and jq tidies the answer. Keep your eye on that last number.
Here we go.
curl -s -H "Authorization: Bearer $(cat token.txt)" http://127.0.0.1:3000/rest/basket/1 | jq '{basket: .data.id, owner_user: .data.UserId, items: [.data.Products[].name]}'
Now look closely at the line that says owner user. This basket belongs to user number one. That is not us. We are logged in on our own account, yet the app cheerfully handed us a stranger’s shopping cart, with their apple, orange, and eggfruit juice.
Now watch what happens when we change just one thing. We take the very same command and turn the one into a two.
curl -s -H "Authorization: Bearer $(cat token.txt)" http://127.0.0.1:3000/rest/basket/2 | jq '{basket: .data.id, owner_user: .data.UserId, items: [.data.Products[].name]}'
A completely different person, user two, and their raspberry juice. Let’s do it one more time, with a three.
curl -s -H "Authorization: Bearer $(cat token.txt)" http://127.0.0.1:3000/rest/basket/3 | jq '{basket: .data.id, owner_user: .data.UserId, items: [.data.Products[].name]}'
User three. Every single time we change that one number, the app shows us another person’s private basket. It checked that we were logged in, but it never checked that these baskets were actually ours. That, in a nutshell, is broken access control.
So how do you handle this flaw?
Find it, and fix it
- FIND: change the I D, see if you get data that isn’t yours
- FIX: the server must check the item is YOURS
- …not just that you are logged in
To find it, you do exactly what we did. Change the I D number, and see if you get back data that should not be yours. To fix it, the server must check ownership. Not just, are you logged in, but, does this basket actually belong to you. That one extra check closes the whole hole.
One rule, always.
Before you go
- Only test apps you own or have permission to test
- Juice Shop is OWASP’s app — run it locally to practice
- Coming next — Part 2: File Inclusion
Only ever test apps you own, or have clear written permission to test. Our juice shop runs only on our own machine, and it was built by O-WASP for exactly this kind of safe practice.
In part two, we will make a web app cough up files it was never meant to show, a flaw called file inclusion. Thanks for learning with The Exploit HQ, and I will see you there.