| CWE | CWE-269, CWE-285 |
| WSTG | WSTG-ATHZ-02, WSTG-ATHZ-03 |
| MITRE ATT&CK | T1068 |
| CVSS Range | 6.5-9.8 |
| Tools | autorize |
| Difficulty | 🔴 advanced |
Vertical Privilege Escalation
Vertical privilege escalation occurs when a lower-privileged user can perform actions or access resources restricted to higher-privileged users, crossing privilege boundaries such as a regular user accessing administrator functionality or a free-tier user unlocking enterprise features. Root causes include missing authorization checks, client-side-only authorization, inconsistent enforcement across API versions, parameter-based role determination from controllable inputs, and insecure direct references to privilege objects like role IDs or permission sets.
Quick Reference​
| Technique | Test | Signal |
|---|---|---|
| Forced browsing | Hit /admin/* endpoints with regular user token | 200 with data = confirmed |
| Role parameter injection | Add "role": "admin" to profile update body | Role changes in response = confirmed |
| Mass assignment | Add "is_admin": true to any PUT/PATCH body | Field accepted and reflected = confirmed |
| HTTP method tampering | Send POST/PUT/PATCH to GET-only admin endpoints | Different response than GET = investigate |
| API version downgrade | Replace /api/v2/ with /api/v1/ or /api/ | Older version returns data = confirmed |
| JWT claim editing | Modify role/admin claims, resign or use alg:none | Token accepted with elevated claims = confirmed |
| Registration with role | Add role/is_admin fields to signup payload | Account created with elevated privileges = confirmed |
Decision flow: Start with admin endpoint discovery and forced browsing. If the application uses JWTs, add JWT manipulation. If you observe role/permission fields in any API response, pursue mass assignment and role parameter injection. Always test across API versions.
Discover Admin Endpoints​
Your first objective is to build a complete map of administrative and privileged endpoints. Applications frequently expose more admin surface area than the UI reveals.
Common admin paths​
Probe these paths using your regular user token. Record the HTTP status code and response body size for each:
/admin
/admin/
/admin/dashboard
/admin/users
/admin/users/list
/admin/settings
/admin/config
/admin/logs
/admin/audit
/admin/reports
/admin/analytics
/manage
/management
/internal
/system
/_admin
/backoffice
/console
/staff
/control
/panel
API admin paths​
/api/admin
/api/admin/users
/api/admin/settings
/api/admin/config
/api/v1/admin
/api/v1/admin/users
/api/v2/admin/users
/internal/api/users
/management/api/users
API documentation endpoints​
Exposed API docs often list admin endpoints that are not linked from the UI:
/swagger
/swagger-ui
/swagger.json
/api-docs
/docs
/api/docs
/openapi.json
/openapi.yaml
/redoc
/graphql
/graphiql
Debug and development endpoints​
These frequently run with elevated privileges or bypass authorization entirely:
/debug
/_debug
/dev
/test
/_test
/staging
/console
/_console
/phpinfo.php
/server-status
/actuator
/actuator/health
/actuator/env
/metrics
/_metrics
/health
/info
Admin subdomain discovery​
Check for admin subdomains. These sometimes share the same backend but apply different authorization rules:
admin.target.com
administrator.target.com
manage.target.com
management.target.com
dashboard.target.com
internal.target.com
staff.target.com
backoffice.target.com
JavaScript analysis for hidden endpoints​
Download and search the application's JavaScript bundles for admin-related paths. Client-side routing definitions and API client code frequently reference endpoints that are hidden from the UI for non-admin users:
Search for these patterns in JS files:
adminnearurl,endpoint,api,route,pathisAdmin,is_admin,hasRole,checkPermissionrole.*admin,permission,authorize- Feature flag references:
feature,flag,enable,canAccess - Route definitions containing admin paths
Also search HTML source for commented-out admin links, hidden form fields (type="hidden"), and href/action attributes referencing admin paths.
Test Forced Browsing​
Forced browsing means directly requesting administrative URLs with a regular user's authentication token, bypassing the UI navigation that would normally prevent access.
Systematic endpoint testing​
For every admin endpoint you discovered above, send a request with your regular user token:
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $REGULAR_USER_TOKEN" \
"https://target.com/admin/users"
Interpret the response:
| Status | Meaning |
|---|---|
| 200 with data | Vertical privilege escalation confirmed. Document immediately. |
| 200 empty | Endpoint exists, may need specific parameters. Investigate further. |
| 301/302 redirect | Check where it redirects. If to a login page, authorization is enforced. If to another admin page, follow it. |
| 403 | Authorization is enforced for this endpoint. Move on to the next. |
| 401 | Authentication issue, not authorization. Verify your token is valid. |
| 404 | Endpoint may not exist, or may be hidden. Try path variations. |
| 405 | Method not allowed. Try other HTTP methods. |
Path variation bypass​
If a path returns 403 or 404, try these variations -- some web servers and frameworks normalize paths differently:
/admin/users (original)
/admin//users (double slash)
/admin/./users (dot segment)
/admin/users/ (trailing slash)
/admin/users? (trailing question mark)
/Admin/Users (case variation)
/ADMIN/USERS (uppercase)
/%61dmin/users (URL-encoded 'a')
/admin/users%00 (null byte)
/admin/users;.js (extension appended)
/admin/users..;/ (Tomcat/Spring bypass)
/admin/users%2e%2e/ (encoded dot-dot)
Identify administrative actions​
Map all actions available to administrators and test each independently with your regular user token:
- User management: create, list, modify, delete, impersonate users
- Role assignment: change user roles, assign permissions
- Configuration: system settings, feature flags, integrations
- Data access: export all data, bulk operations, reports, audit logs
- Security controls: 2FA settings, IP allowlists, session policies
For each action, construct and send the corresponding API request. Do not assume that because one admin endpoint is protected, all of them are.
Manipulate Role Parameters​
Applications sometimes accept role or privilege information in request parameters, allowing self-assignment of elevated privileges.
Identify role parameters​
Monitor all requests for role-related fields in these locations:
- Request body:
role,user_role,privilege,level,tier,type,account_type,permissions,is_admin,isAdmin,admin - Headers:
X-User-Role,X-Permission,X-Admin,X-Forwarded-User - Query parameters:
role=,admin=,tier=,level= - Cookies:
role=,admin=,isAdmin=
Test role values​
When you find a role-related parameter, try these values:
"admin", "administrator", "Admin", "ADMIN"
"superadmin", "super_admin", "superuser"
"root", "system", "internal"
"moderator", "mod", "manager"
"staff", "employee", "support"
1, 0, -1, 999
true, True, "true"
{"admin": true}
["admin"]
"*"
Header-based role injection​
Some applications behind reverse proxies or API gateways read role information from HTTP headers. Test injecting these headers alongside your regular user token:
X-User-Role: admin
X-Admin: true
X-Forwarded-User: admin@company.com
X-Original-User: admin
X-Remote-User: admin
X-Auth-Role: admin
Self-role modification endpoints​
Attempt to directly change your own role through user profile or account endpoints:
# Profile update with role field
PUT /api/users/me {"role": "admin"}
PATCH /api/users/me {"role_id": 1}
PUT /api/me/role {"role": "admin"}
# Permission self-grant
POST /api/me/permissions {"permission": "admin.users.manage"}
# Group self-assignment
POST /api/me/groups {"group_id": "admin-group"}
# Account type escalation
PUT /api/account {"account_type": "enterprise"}
PUT /api/subscription {"tier": "premium"}
Registration with elevated privileges​
Test whether new account registration accepts privilege-related fields:
POST /api/register
{
"email": "test@example.com",
"password": "password123",
"role": "admin",
"is_admin": true,
"account_type": "enterprise",
"permissions": ["admin"]
}
Also test invite/referral acceptance flows for role parameter injection:
POST /api/accept-invite
{
"token": "invite_token",
"role": "admin"
}
Exploit Mass Assignment​
Mass assignment vulnerabilities occur when an API endpoint binds request parameters directly to internal model attributes without filtering. If the user model has an is_admin field, and the profile update endpoint does not explicitly exclude it, you can set it by including it in the request body.
Testing approach​
Take any endpoint that updates user data (profile, settings, preferences) and add privilege-related fields that you would not normally see in the form:
# Normal profile update
PUT /api/users/me
{"name": "Test User", "email": "test@example.com"}
# Mass assignment attempt
PUT /api/users/me
{
"name": "Test User",
"email": "test@example.com",
"is_admin": true,
"role": "admin",
"permissions": ["admin.full"],
"account_type": "enterprise",
"verified": true,
"email_verified": true,
"two_factor_enabled": false,
"subscription_tier": "enterprise"
}
Fields to inject​
Try adding these fields to any user-modifiable endpoint:
is_admin, isAdmin, admin, role, user_role
permissions, scopes, grants, privileges
account_type, tier, subscription_tier, plan
verified, email_verified, phone_verified
active, enabled, approved, confirmed
two_factor_enabled, mfa_required
organization_role, org_admin, team_role
created_by, owned_by, managed_by
Verification​
After each mass assignment attempt, immediately query your user profile or account details to check whether the injected fields were accepted:
GET /api/users/me
Compare the response with your pre-attack baseline. If any privilege-related field changed, verify that the new privilege actually grants elevated access by attempting a previously-forbidden admin action.
Tamper with HTTP Methods​
Authorization checks are sometimes applied only to specific HTTP methods. An endpoint that blocks GET requests from regular users may allow POST, PUT, PATCH, or DELETE.
Systematic method testing​
For each admin endpoint, try every standard HTTP method:
GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD, TRACE
Pay special attention to:
- OPTIONS: May return allowed methods and bypass authorization
- HEAD: Sometimes processes the request but returns no body -- check if side effects occur
- TRACE: May reflect back request details including internal headers
HTTP method override headers​
Some frameworks support overriding the HTTP method via headers. This can bypass method-specific authorization:
X-HTTP-Method-Override: DELETE
X-Method-Override: PUT
X-HTTP-Method: PATCH
_method=PUT (as query parameter or form field)
Send a POST request with these override headers to test whether the framework processes it as the overridden method while the authorization layer only checks the original POST method.
Content-Type manipulation​
Try different content types on admin endpoints. Some authorization middleware only inspects certain content types:
Content-Type: application/json
Content-Type: application/xml
Content-Type: application/x-www-form-urlencoded
Content-Type: multipart/form-data
Content-Type: text/plain
Bypass via API Version Downgrade​
Older API versions frequently lack authorization checks that were added in newer versions. If the current API is /api/v2/, the /api/v1/ or unversioned /api/ equivalent may still be active and unprotected.
Version downgrade testing​
For every protected admin endpoint you encounter, systematically try:
/api/v2/admin/users (current, returns 403)
/api/v1/admin/users (older version)
/api/v0/admin/users (initial version)
/api/admin/users (unversioned)
/admin/users (no api prefix)
/v1/admin/users (alternative structure)
/v2/admin/users (alternative structure)
Accept header versioning​
Some APIs version via the Accept header rather than the URL path:
Accept: application/vnd.api.v1+json
Accept: application/vnd.api.v2+json
Accept: application/vnd.api+json; version=1
Try requesting admin endpoints with older version Accept headers while using the current URL path.
Deprecated endpoint formats​
Check for deprecated endpoint naming patterns that may still be routed to the same backend handlers:
/api/v1/admin/users (RESTful)
/api/v1/getAdminUsers (RPC-style)
/api/v1/admin_users (snake_case)
/api/v1/AdminUsers (PascalCase)
/jsonrpc (with method: "admin.getUsers")
/graphql (with admin queries)
Manipulate JWT Role Claims​
If the application uses JWTs for authentication, the token may contain role or privilege claims that can be modified.
Analyze token structure​
Decode the JWT and examine its claims:
# Decode header
echo "$JWT" | cut -d. -f1 | base64 -d 2>/dev/null
# Decode payload
echo "$JWT" | cut -d. -f2 | base64 -d 2>/dev/null
Look for any of these claim fields: role, roles, admin, is_admin, permissions, scope, scopes, groups, tier, level, type, aud, sub (may encode role info).
None algorithm attack​
If the server does not validate the algorithm field:
- Change the JWT header to
{"alg": "none", "typ": "JWT"} - Modify the payload claims to include elevated privileges (e.g.,
"role": "admin") - Remove the signature (third segment), leaving a trailing dot
- Send the modified token
Algorithm confusion (RS256 to HS256)​
If the server uses RS256 (asymmetric) and you can obtain the public key:
- Change the header algorithm to HS256
- Modify payload claims for elevated privileges
- Sign the token using the public key as the HMAC secret
- Send the modified token
Claim modification with weak secrets​
If you can crack or guess the JWT signing secret (try common secrets like secret, password, key, jwt_secret, the application name), forge a new token with elevated claims:
Original: {"sub": "user123", "role": "user", "admin": false}
Modified: {"sub": "user123", "role": "admin", "admin": true}
Token response analysis​
Check if any API response returns a new JWT with different claims than what you sent. Some applications issue upgraded tokens in response to certain actions (login, profile update, session refresh) and you can examine these for privilege-related changes.
Escalate Across Tenants​
In multi-tenant applications, vertical escalation can also mean crossing tenant boundaries to gain administrative access in another tenant's context.
Cross-tenant admin access​
If the application uses tenant identifiers (in headers, subdomains, URL path, or token claims):
- Identify how tenant context is established (header like
X-Tenant-ID, subdomain, path prefix, JWT claim) - Attempt to access admin endpoints while manipulating the tenant identifier
- Test whether your admin credentials in Tenant A grant admin access in Tenant B
- Test whether a regular user in Tenant A can access admin endpoints in Tenant B by manipulating the tenant identifier
Organization role escalation​
In applications with organization/team hierarchies:
# Attempt to escalate from member to org admin
PUT /api/orgs/ORG_ID/members/me {"role": "owner"}
# Create a new org where you are admin, then test cross-org access
POST /api/orgs {"name": "my-org"}
# Now try accessing admin endpoints with the admin token from your org
Shared infrastructure exploitation​
If multiple tenants share infrastructure components (shared admin panels, shared API gateways), test whether authentication from one tenant grants access to shared administrative endpoints.
Document the PoC​
When documenting a vertical privilege escalation finding:
-
Establish baseline: Show that your test account is a regular user. Include the response from
GET /api/users/meor equivalent showing your role. -
Show the escalation: Provide the exact HTTP request (method, URL, headers, body) that achieves the escalation. Include the response.
-
Verify functional impact: Demonstrate that the escalated privilege actually grants new capabilities. Access an admin endpoint, modify a setting, or perform an admin action that was previously forbidden.
-
Show persistence (if applicable): If the privilege change persists across sessions, demonstrate this by logging out and back in, then showing the elevated access still works.
-
Assess scope: Document what an attacker could do with the escalated privileges. Can they access other users' data? Modify system configuration? Create backdoor admin accounts?
-
Provide cleanup steps: Describe how to revert the privilege escalation (remove the role, delete the created admin account, etc.).
Always use test accounts you control. Never modify real users' privileges. If you must demonstrate impact on other accounts, use the minimum necessary action and document the revert procedure.
Tools​
| Tool | Use Case |
|---|---|
| curl / httpx | Direct API requests with custom headers, methods, and bodies |
| Burp Suite | Intercept and modify requests, especially useful for swapping tokens between user and admin sessions |
| Postman | Organize and replay admin endpoint requests with different auth contexts |
| jwt_tool | JWT analysis, claim modification, algorithm confusion attacks, secret brute-forcing |
| ffuf / feroxbuster | Directory and file brute-forcing for hidden admin paths |
| Gobuster | Admin subdomain and path enumeration |
| Arjun | Hidden parameter discovery on admin endpoints |
| ParamSpider | Extract parameters from web archives for mass assignment testing |
| LinkFinder | Extract endpoints from JavaScript files |
| SecretFinder | Find secrets and API keys in JS that might grant admin access |
Minimum Coverage Checklist​
Before completing this task, verify you have tested:
- Direct admin endpoint access with regular user token
- API version variations (v1, v2, unversioned)
- Role parameter injection in request body, headers, and cookies
- Self-role modification through profile/account update endpoints
- Mass assignment with
is_admin,role,permissionsfields on all writable endpoints - Permission and group self-assignment
- Hidden admin endpoints discovered from JavaScript analysis
- HTTP method variations (GET, POST, PUT, PATCH, DELETE) on protected endpoints
- HTTP method override headers
- Path manipulation bypasses (encoding, case, traversal, null byte)
- JWT/token claim modification (if JWT-based auth)
- Registration with elevated privilege fields
- Account type/tier escalation
- Bulk/batch operation authorization
- Content-Type variations on admin endpoints
- Debug/internal/actuator endpoints
- API documentation endpoints for admin route discovery
- Cross-tenant admin access (if multi-tenant)
Document every test with the request, response, and your interpretation in the work log.
Prioritization​
Test these first (highest real-world exploitability)​
- Forced browsing to admin endpoints -- EPSS >0.6 for authorization bypass CVEs. Simply access
/admin/*,/api/admin/*, or/internal/*endpoints with a regular user token. Missing authorization checks on admin routes are extremely common. - Mass assignment / role parameter injection -- Add
"role": "admin","is_admin": true, or"permissions": ["*"]to profile update or registration requests. Frameworks that auto-bind request parameters are vulnerable by default. - HTTP method tampering on admin endpoints -- If GET is allowed but POST is restricted, try the reverse. Also test
PUT,PATCH,DELETE, and method override headers (X-HTTP-Method-Override).
Test these if time permits (lower exploitability)​
- API version inconsistency -- Older API versions (
/api/v1/vs/api/v2/) may lack authorization checks added in newer versions. Test deprecated endpoints. - Function-level access control bypass via parameter manipulation -- Change function IDs, feature flags, or tier identifiers in requests to access premium/enterprise features.
- JWT claim escalation -- Modify role/permission claims in JWT tokens. Only exploitable if signing secret is weak or algorithm confusion is possible.
Skip if​
- Application has a single user role with no privilege differentiation
- Authorization is enforced at a gateway/middleware layer that applies uniformly to all routes (verified by testing, not assumed)
- No admin panel or privileged functionality exists in the application
Asset criticality​
Prioritize by privilege gap: regular user to system admin > regular user to org admin > free tier to paid tier > read-only to read-write. Vertical escalation on endpoints managing users, billing, or system configuration is always Critical. Focus on the highest-privilege endpoints first.