Full-Stack Playground
Live Demo
An interactive app covering every layer of full-stack web development. Learn by doing.
TOTAL TASKS
0
ā stored in memory DB
COMPLETED
0
tasks finished
API CALLS
0
REST requests made
š
Frontend + CRUD
Forms, DOM manipulation, REST calls
ā
ā”
REST API Design
Endpoints, methods, status codes, JSON
ā
š
Database & SQL
Schema, queries, relations, live SQL runner
ā
š
Auth & JWT
Tokens, sessions, hashing, cookies
ā
š”
Security & Bug Bounty
XSS, SQLi, IDOR, CSRF explained
ā
š„
Server & HTTP
Headers, CORS, cookies, Node.js
ā
Every web request travels through these layers. Understanding this is the foundation of bug bounty.
BROWSER
User fills form ā JS fires fetch() ā HTTP request created
ā
NETWORK
DNS ā TCP handshake ā TLS ā Packet routing
ā
SERVER
Router ā Middleware ā Auth check ā Controller
ā
DATABASE
SQL query ā fetch rows ā return JSON
ā
RESPONSE
HTTP 200 + JSON ā JS updates DOM
01
Frontend + CRUD Operations
This simulates how a real app works: form input ā API call ā database write ā UI update. The "database" here is JavaScript's in-memory array.
Create Task (POST /api/tasks)
TASK TITLE
DESCRIPTION
PRIORITY
Low
Medium
High
CATEGORY
Bug
Feature
Security
Docs
+ Create Task (POST)
const response = await fetch ('/api/tasks' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' ,
'Authorization' : `Bearer ${token}` },
body : JSON.stringify ({ title, priority })
});
const data = await response.json ();
// data = { id: 42, title: '...', createdAt: '...' }
Task List (GET /api/tasks)
All
High
Medium
Low
Sort ā
No tasks yet. Create one on the left ā
HTTP Response Codes You'll See
200
OK ā request succeeded
201
Created ā POST succeeded
401
Unauthorized ā no/bad token
403
Forbidden ā token valid, no access
404
Not Found ā resource missing
422
Unprocessable ā bad input data
500
Server Error ā backend crashed
302
Redirect ā move to new URL
02
REST API Design
REST (Representational State Transfer) is a design pattern for building APIs. Click any endpoint to simulate the request and see the response structure.
Response Viewer
ā Click an endpoint to simulate a request
RESTful Principles
Nouns URLs describe resources, not actions: /tasks not /getTasks
Verbs HTTP methods do the work: GET=read, POST=create, PUT=update, DELETE=remove
State Server is stateless ā each request must carry auth (Bearer token or cookie)
JSON Standard data format for request bodies and responses
Node.js / Express Route Implementations
const express = require ('express' );
const router = express.Router ();
// GET all tasks ā requires auth middleware
router.get ('/tasks' , authenticate , async (req, res) => {
const tasks = await db.query ('SELECT * FROM tasks WHERE user_id=$1' , [req.user.id]);
res.json ({ tasks: tasks.rows });
});
// POST create ā validates input
router.post ('/tasks' , authenticate , async (req, res) => {
const { title, priority } = req.body;
if (!title) return res.status (422 ).json ({ error: 'Title required' });
const task = await db.query ('INSERT INTO tasks(title,priority,user_id) VALUES($1,$2,$3) RETURNING *' , [title, priority, req.user.id]);
res.status (201 ).json (task.rows[0 ]);
});
// DELETE ā checks ownership (prevents IDOR)
router.delete ('/tasks/:id' , authenticate , async (req, res) => {
const task = await db.query ('DELETE FROM tasks WHERE id=$1 AND user_id=$2 RETURNING *' , [req.params.id, req.user.id]);
if (!task.rows.length) return res.status (404 ).json ({ error: 'Not found' });
res.json ({ deleted: true });
});
03
Database & SQL
Databases store persistent data. Understanding schema design and SQL is critical ā it's where SQL Injection vulnerabilities live.
Schema ā Tables
id SERIAL PK auto-increment
username VARCHAR(50) UNIQUE NOT NULL
email VARCHAR(100) UNIQUE NOT NULL
password_hash VARCHAR(60) bcrypt hash ā never plain text!
role ENUM 'user' | 'admin'
created_at TIMESTAMP DEFAULT NOW()
id SERIAL PK
user_id INTEGER FK ā users.id (ownership!)
title VARCHAR(200) NOT NULL
description TEXT nullable
priority ENUM 'low' | 'medium' | 'high'
status ENUM 'todo' | 'done'
created_at TIMESTAMP DEFAULT NOW()
SQL Query Runner
Practice SQL queries against the in-memory task database.
-- Load a preset query --
SELECT all tasks
SELECT high priority tasks
COUNT by status
JOIN users + tasks
INSERT example
ā SQLi vulnerable query
ā
SQLi safe parameterized
ā¶ Run Query
Key SQL Concepts for Bug Bounty
Primary Keys
Unique identifier for each row. In bug bounty: incrementing IDs (1, 2, 3ā¦) are vulnerable to IDOR ā you can guess other users' resource IDs.
Foreign Keys
Links rows across tables. tasks.user_id ā users.id. If the server doesn't check this on DELETE/GET, attacker can access other users' tasks.
Parameterized Queries
The defense against SQLi. Pass user input as $1 parameter, never concatenate strings directly into SQL.
04
Authentication & JWT
Auth is one of the most bug-bounty-rich areas. Understand how it works to find where it breaks.
Login Simulator
USERNAME
PASSWORD
Login ā Generate JWT
Generated JWT Token
. .
HEADER (red)
PAYLOAD (green)
SIGNATURE (blue)
How JWT Works
1
User submits username + password to /api/login
2
Server checks password against bcrypt hash in DB (never compare plaintext!)
3
Server creates JWT: header.payload.signature ā payload contains user ID, role, expiry
4
Client stores JWT in localStorage or HttpOnly cookie
5
Every future request sends JWT in Authorization: Bearer <token> header
6
Server verifies signature using secret key ā if tampered, signature fails
Bug Bounty Auth Weaknesses
ā alg: none ā some servers accept JWTs with no signature if algorithm is "none"
ā Weak secret ā if JWT secret is "secret" or "password", it can be brute-forced
ā No expiry ā tokens without exp claim never expire, stolen tokens work forever
ā localStorage XSS ā if JWT is in localStorage, XSS can steal it
05
Security Vulnerabilities (Bug Bounty)
The OWASP Top 10 are the most common web vulnerabilities. Click each to expand the explanation and see where it hides in this app.
Security Headers Checker
HTTP response headers can prevent many attacks. Check what a server should send:
06
Server & HTTP Internals
Understand the server layer ā where middleware, CORS, cookies, and request parsing happen.
Interactive HTTP Terminal
Simulate curl commands. Type commands below.
$
GET /api/tasks
POST /api/login
headers
CORS
cookies
middleware
Node.js Server Structure
const express = require ('express' );
const app = express ();
// 1. Parse JSON bodies
app.use (express.json ());
// 2. CORS ā allow specific origins
app.use (cors ({ origin: 'https://myapp.com' , credentials: true }));
// 3. Rate limiting (prevents brute force)
app.use (rateLimit ({ windowMs: 15 *60000 , max: 100 }));
// 4. Auth middleware ā verify JWT
function authenticate (req, res, next) {
const token = req.headers.authorization?.split(' ' )[1 ];
if (!token) return res.status (401 ).json ({ error: 'No token' });
req.user = jwt.verify (token, process.env.JWT_SECRET);
next ();
}
app.listen (3000 );