Access Control Review & Practice
A curated set of progressively harder access-control challenges. IDOR, path traversal, privilege escalation, mass assignment, JWT — no hand-holding. The AC course final.
A curated set of progressively harder access-control challenges. IDOR, path traversal, privilege escalation, mass assignment, JWT — no hand-holding. The AC course final.
This final lesson presents a curated set of progressively harder access-control challenges drawn from the techniques covered in this course: IDOR, path traversal, privilege escalation, mass assignment, JWT attacks, and CSRF. Each challenge provides a target description, a code snippet hint, and a payload entry field. The goal is to craft the correct exploit payload that demonstrates the vulnerability.
Each challenge simulates a real application endpoint with a missing access control. You are given the application code (or a relevant snippet), a description of the target, and a prompt to craft the exploit payload. Challenges progress from simple parameter manipulation to multi-step attacks combining JWT confusion with CSRF.
Pick a challenge, craft the exploit payload, and press Submit. The key tokens in your payload must match the canonical answer.
You are logged in as user_id=3. The profile endpoint returns any profile by ID. Craft the request to read another user's data.
app.get('/api/profile/:id', async (req, res) => {
const profile = await db.query(
'SELECT * FROM profiles WHERE id = $1',
[req.params.id],
);
res.json(profile.rows[0]);
});Hint: Change the user_id parameter to a different value. Try /api/profile/1 or /api/profile/2.
The five challenge classes appear in multiple OWASP Top 10 entries and account for the majority of access-control bug bounty submissions:
Mastering these five scenarios means you can recognise the majority of access-control vulnerabilities you will encounter in the wild — and you know how to fix each one.
// CHALLENGE 1: IDOR — add ownership check
app.get('/api/profile/:id', async (req, res) => {
const profile = await db.query(
'SELECT * FROM profiles WHERE id = $1 AND user_id = $2',
[req.params.id, req.session.userId],
);
if (!profile.rows[0]) return res.status(403).end();
res.json(profile.rows[0]);
});
// CHALLENGE 2: Path traversal — canonicalise
const requested = path.resolve('/var/www/uploads', req.params.file);
if (!requested.startsWith('/var/www/uploads')) {
return res.status(403).end();
}
// CHALLENGE 3: JWT alg=none — enforce algorithm whitelist
jwt.verify(token, secret, { algorithms: ['HS256'] });
// CHALLENGE 4: CSRF — use anti-forgery token + SameSite=Strict
app.post('/api/transfer', csrfProtection, (req, res) => { ... });1.An API endpoint reads /var/www/files/ + req.params.filename. What is the vulnerability?
2.A JWT library accepts tokens with an alg header value of "none". What does the attacker gain?
3.Which defence prevents CSRF when an attacker hosts a form on their own site that submits to your application?