Web Hacking Labs

Interactive security vulnerability labs — learn by exploiting

Server-Side Client-Side
Server-Side

IDOR

Insecure Direct Object Reference

Access another user's information by manipulating object references.

Solved
Server-Side

Broken Access Control

Client-Side Access Controls

Bypass client-side restrictions to perform unauthorized actions.

Solved
Client-Side

XSS

Cross-Site Scripting

Inject malicious scripts into a vulnerable web page.

Solved
Client-Side

CSRF

Cross-Site Request Forgery

Force a victim to perform an unwanted action.

Solved
[CLASSIFIED]

[REDACTED]

████████

This lab is locked. Or is it?

Solved
← Back

Server-Side IDOR Lab

What is IDOR?

Insecure Direct Object Reference (IDOR) occurs when an application exposes internal object references (like database IDs) to users, allowing them to access resources belonging to other users.

Example

You are a user with ID 3. By changing the ID in the URL to 1, you can access another user's profile—including sensitive information.

Your Mission

  1. Generate credentials and log in
  2. Find the user ID parameter in the URL
  3. Modify it to access another user's data
  4. Bonus: Can you use the Network tab in your Developer Tools to find some additional information leaked about the users that is not displayed in the UI?
🔎

SecureCorp Portal

A user profile viewer. Log in, find the id parameter in the browser URL bar, and try changing it.

Open Lab →

Solution

The API endpoint /api/viewUser?id=X does not verify that the requesting user is authorized to view the specified profile.

Exploitation Steps

  1. Login and note your assigned user ID in the URL (e.g., ?id=5)
  2. Change the id parameter to a nearby value (e.g., ?id=4 or ?id=6)
  3. Observe that you can access any other user's personal information

Bonus: Did you check the Network tab?

If you open DevTools (F12) → Network tab and inspect the raw API response, you'll notice the server sends back more data than what's displayed on the page. APIs often leak sensitive fields that the frontend simply chooses not to render.

Bug Bounty Report

Lab Solved

## Summary

An Insecure Direct Object Reference (IDOR) vulnerability was identified in the user profile endpoint at /api/viewUser. The endpoint accepts a user ID parameter without verifying the requesting user is authorized to view that profile, allowing any authenticated user to access other users' personal information.

## Reproduction Steps

  1. Login to the application using the "Generate Credentials" button
  2. Note your assigned user ID in the URL (e.g., ?id=5)
  3. Modify the id parameter to access another user's profile:
  4. Observe that the other user's profile information is displayed

## Impact

An attacker can enumerate user IDs to access any user's personal information including name, email, and phone number. This constitutes a data breach affecting all users of the platform. Sequential IDs make enumeration trivial, allowing bulk data extraction.

← Back

Server-Side Broken Access Control Lab

What is Broken Access Control?

Broken Access Control occurs when an application enforces restrictions only on the client-side (in the browser) but not on the server. A user can bypass these UI restrictions to perform actions they shouldn't be allowed to do.

Example

You have a "Read-Only" role. The buttons to edit and delete are grayed out in the UI, but the server doesn't actually check your role—so if you re-enable the buttons, the actions work.

Your Mission

  1. Generate credentials and log in as a read-only user
  2. Observe that all action buttons are disabled
  3. Find a way to remove the disabled attribute from the buttons
  4. Confirm that the actions actually execute on the server—not just a UI change
📝

SecureCorp Notes

A notes manager where you're a read-only user. All buttons are disabled—or are they? Open DevTools and find out.

Open Lab →

Solution

The application only enforces access controls on the client-side using the HTML disabled attribute. The server-side API endpoints do not check the user's role at all.

Step 1: Inspect Element

  1. Login and observe the "Read-Only User" badge and disabled buttons
  2. Right-click on any disabled button and select Inspect (or press F12)
  3. In the Elements panel, find the disabled attribute on the button element
  4. Double-click the attribute and delete it, or right-click → Edit attribute → remove disabled
  5. The button is now clickable — click it and confirm the action actually executes on the server

Step 2: Let's Write an Automated Exploit

Manually removing disabled from each element works, but in a real bug bounty report you'd want a reproducible exploit a client or triager can run instantly. Open DevTools (F12) → Console and paste this one-liner:

document.querySelectorAll('[disabled]').forEach(el => el.removeAttribute('disabled'))

What this does:

  • document.querySelectorAll('[disabled]') — finds every element on the page that has the disabled attribute
  • .forEach(el => ...) — iterates over each one
  • el.removeAttribute('disabled') — removes the attribute, re-enabling the element

All buttons and inputs are now enabled. Click any action button to confirm the server actually processes the request—this is not just a UI trick. Notes are really created, updated, and deleted on the server.

Bug Bounty Report

Lab Solved

## Summary

A Broken Access Control vulnerability exists where user permissions are enforced only via the HTML disabled attribute on the client-side. The server-side API endpoints (/api/notes) perform no role-based authorization checks, allowing read-only users to create, modify, and delete notes.

## Reproduction Steps

  1. Login using "Generate Credentials" and observe the "Read-Only User" role
  2. Confirm all action buttons (Edit, Delete, Add Note) are disabled in the UI
  3. Open Developer Tools (F12) → Console
  4. Paste the following JavaScript one-liner:
  5. Click any now-enabled button (e.g., "Delete" on a note)
  6. Confirm the action actually executes on the server—the note is really deleted, not just hidden from the UI. Refresh the page to verify the change persists.

## Impact

Any user with a read-only role can bypass client-side restrictions to perform full CRUD operations on all notes. This undermines the entire role-based access control system. A malicious read-only user could modify or delete critical security documentation, create misleading entries, or exfiltrate data through note creation.

← Back

Client-Side XSS Lab

What is XSS?

Cross-Site Scripting (XSS) occurs when an application includes untrusted data in a web page without proper sanitization. An attacker can inject HTML and JavaScript code that executes in the victim's browser.

Example

An attacker sends a link to a victim. When the victim clicks it, the attacker's JavaScript runs in the victim's browser—stealing their session token.

Your Mission

  1. Generate credentials to establish a session (cookie is set)
  2. Find the search functionality and notice the query is in the URL
  3. Craft a search query that injects a <script> tag
  4. Extract the session token from document.cookie
💻

SecureCorp Notes — Search

A notes app with search. Log in, then try searching. Notice the q parameter in the URL—what happens if you put something unexpected in there?

Open Lab →

Solution

The search endpoint at /lab/xss/search?q=... reflects the query parameter directly into the HTML response without sanitization, enabling Reflected XSS.

Exploitation Steps

  1. Login to establish a session (a session_token cookie is set)
  2. Enter the following payload in the search box (or navigate directly to the URL):
<script>alert('pwned ',document.cookie)</script>

Full Exploit URL

/lab/xss/search?q=<script>alert('pwned ',document.cookie)</script>

When the victim visits this URL, the JavaScript executes in their browser, and an alert box displays pwned along with their session token. In a real attack, the token would be sent to an attacker-controlled server instead of displayed in an alert.

Bug Bounty Report

Lab Solved

## Summary

A Reflected Cross-Site Scripting (XSS) vulnerability was identified in the search functionality at /lab/xss/search. The q query parameter is reflected directly into the HTML response without sanitization, allowing arbitrary JavaScript execution in the context of an authenticated user's browser session.

## Reproduction Steps

  1. Login to the application using the "Generate Credentials" button (this sets a session_token cookie)
  2. Navigate to the following URL:
  3. Observe that an alert box appears displaying pwned (the session cookie is passed as the second argument and visible in the console)

## Impact

An attacker can craft a malicious link that, when visited by an authenticated user, executes arbitrary JavaScript in their browser. This enables session hijacking via cookie theft, performing actions on behalf of the victim, or redirecting them to a phishing page. Since the session token is accessible to JavaScript (not HttpOnly), full account takeover is achievable.

← Back

Client-Side CSRF Lab

What is CSRF?

Cross-Site Request Forgery (CSRF) occurs when an attacker tricks an authenticated user into making an unintended request to a web application. Because the browser automatically includes cookies, the server treats it as a legitimate action.

Example

An attacker sends a link to a victim. When the victim clicks the link, their account gets deleted—because the browser sends the session cookie along with the request automatically.

Your Mission

  1. Generate credentials and log in
  2. Find the "Delete Account" functionality and observe how it works
  3. Notice the deletion happens via a simple GET request
  4. Craft a link an attacker could send to a victim to delete their account
🔗

SecureCorp Account

An account settings page with a "Delete Account" button. Log in, then look at how the deletion works. Could someone trick you into clicking a link?

Open Lab →

Solution

The account deletion endpoint uses a GET request at /deleteAccount with no CSRF token or confirmation. Since GET requests can be triggered by simply navigating to a URL, an attacker can trick a victim into deleting their own account.

Exploitation Steps

  1. Login to establish a session
  2. The "Delete Account" button simply navigates to:
/deleteAccount

An attacker sends this link to the victim (via email, chat, etc.). When the authenticated victim clicks it, their browser sends the session cookie automatically, and the server deletes their account.

Why This Works

  • State-changing action via GET request (should be POST/DELETE)
  • No CSRF token required
  • No confirmation step
  • Browser automatically sends cookies with the request

Bug Bounty Report

Lab Solved

## Summary

A Cross-Site Request Forgery (CSRF) vulnerability exists in the account deletion functionality. The /deleteAccount endpoint accepts unauthenticated GET requests and relies solely on the session cookie for authorization, with no CSRF token or confirmation mechanism.

## Reproduction Steps

  1. Login to the application using the "Generate Credentials" button
  2. In a new tab or via a link, navigate to:
  3. Observe that your account has been permanently deleted without any confirmation

## Impact

An attacker can craft a malicious link that, when clicked by an authenticated victim, permanently deletes their account. The link can be distributed via phishing emails, social media, or embedded in a webpage as an image tag. No user interaction beyond clicking the link is required. This vulnerability affects all authenticated users of the platform.

← Back

[CLASSIFIED] [REDACTED]

Final Challenge

You've learned about IDOR, Broken Access Control, XSS, and CSRF. Now put your skills together.

Use what you've learned in the previous labs to find the password for the user with ID 100.

Challenge Complete

Enter the Password

What is the password for user ID 100?