What Is Privilege Escalation? Types, Examples & Prevention in Web Applications
Privilege escalation (PrivEsc) is one of the most critical vulnerabilities in web applications. This guide explains horizontal vs. vertical privilege escalation, real-world attack techniques like parameter manipulation, SQL injection, and insecure file uploads, and the access control failures that enable them — plus how to prevent them.
Privilege Escalation in Web Applications: What Technical Leaders Need to Know
Privilege escalation is the attack class that keeps security engineers up at night, and for good reason. Whether it surfaces as a misconfigured API endpoint, an over-permissioned AI agent, or a SQL injection buried in legacy code, a successful privilege escalation attack can hand an adversary the keys to your entire infrastructure. For engineering and security leaders, understanding how these attacks work, and where your defenses are most likely to fail, is foundational to building resilient systems.
What Is Privilege Escalation?
Privilege escalation (PrivEsc) is any attack in which an adversary expands their access beyond what has been authorized. In the best case for the attacker, they move from unauthenticated visitor to root server access in a single step. More commonly, they chain together multiple smaller escalations: from anonymous user, to authenticated user, to privileged role, to server foothold, and finally to admin or root.
Privilege escalation is fundamentally a symptom of weak, incomplete, or missing access controls. Effective access control is the combination of three distinct layers:
- Authentication: Verifying the identity of the requesting party (user, service, or agent).
- Session management: Binding that verified identity to subsequent requests through tokens or session state, so the application does not re-verify identity on every call.
- Authorization enforcement: Confirming that the authenticated identity is actually permitted to perform the requested action on the requested resource.
When any of these layers has a gap, attackers have a pathway to escalate. Broken access control has ranked as the number one application security risk in the OWASP Top 10 for several consecutive cycles, and remains 100% prevalent across applications assessed in the latest release.
Web and API Applications: Why the Attack Surface Is Different
Privilege escalation in web and API applications is materially harder to defend than its network counterpart, primarily because the attack surface is far larger and more dynamic. Every URL, static file, API endpoint, and accepted HTTP verb (GET, POST, PUT, DELETE, PATCH, and so on) is a potential target. A single SaaS application with hundreds of routes, multiple user roles, and configurable permissions can easily surface dozens of exploitable access control gaps.
Modern architectures compound this. Microservices expose internal APIs that may lack the same enforcement applied to external-facing surfaces. GraphQL introspection leaks schema details. Serverless functions may run with overly broad IAM roles. The combination creates a fragmented authorization perimeter that is difficult to reason about holistically.
The Two Fundamental Categories
Horizontal Privilege Escalation
Horizontal escalation involves moving laterally to access resources belonging to another user or tenant at the same privilege level. A classic example: in a multi-tenant SaaS platform, an attacker manipulates a request parameter to retrieve another tenant's data without needing to elevate to an administrative role. In a banking application, this means accessing another customer's account, not the admin console.
Horizontal escalation is frequently exploited through Insecure Direct Object References (IDOR), where predictable identifiers (auto-incrementing integers, sequential UUIDs) are used to reference records directly without server-side ownership checks.
Vertical Privilege Escalation
Vertical escalation involves moving up the permission hierarchy. An unauthenticated user gaining authenticated access, or an authenticated user accessing administrative functionality, are both vertical escalations. The most severe form is obtaining root or admin access to the underlying server.
Horizontal and vertical escalation are often chained together. An attacker who compromises a standard user account via horizontal escalation may discover that account has administrative access to a specific subsystem, effectively achieving vertical escalation by proxy.
The Five Primary Attack Techniques
1. Parameter Manipulation:
Parameter manipulation exploits the gap between what the client presents and what the server verifies. Consider a request like:
GET /retrieveaccount?accountID=12345 HTTP/1.1
Host: vulnsaas.comIf the server returns the account matching the provided ID without verifying that the authenticated session owns that account, incrementing or fuzzing the accountID value exposes every account in the system. The same pattern applies to user IDs, order numbers, document references, and any other resource identifier passed through query strings, path parameters, or request bodies.
The mitigation is strict server-side ownership checks on every resource retrieval, regardless of whether the identifier is "hidden" from the UI. Security through obscurity is not access control.
2. Missing Server-Side Authorization Enforcement
This is one of the most prevalent and dangerous categories. Consider an application where the admin UI exposes five menu items but the standard user interface only renders three. The two restricted items are simply hidden from the regular user's view. If the underlying API endpoints (/api/v2/discussions, /api/v2/settings) do not independently enforce authorization, any user who knows or discovers those routes can access them directly, bypassing the client-side restriction entirely.

The same pattern applies to HTTP verb abuse: an endpoint that allows GET /api/v2/documents/user for regular users may also accept POST /api/v2/documents/all without checking whether the requesting user is authorized to perform that broader operation. Relying on UI state or route obscurity as a substitute for server-side authorization checks is a systemic failure. Every endpoint must enforce authorization independently, regardless of whether it appears in the interface.

Relying on UI state or route obscurity as a substitute for server-side authorization checks is a systemic failure. Every endpoint must enforce authorization independently, regardless of whether it appears in the interface.
3. Command Injection
Command injection allows an attacker to execute operating system commands through the application layer, escalating from web user to server console. The classic vulnerability pattern:
String comm = "cmd.exe /c dir " + request.getParameter("file");
Process process = Runtime.getRuntime().exec(comm);
An attacker passing .; ipconfig -a as the file parameter executes arbitrary commands server-side. From there, privilege escalation to root or admin depends on the process's running context and what additional vulnerabilities exist on the host.
The mitigation is straightforward: avoid shelling out to the operating system from application code entirely. If system commands are genuinely necessary, implement a strict allowlist of permitted commands and arguments, and never concatenate user-supplied input into command strings.
4. SQL Injection
SQL injection enables attackers to manipulate the database queries the application constructs, and in certain configurations it provides a direct path to server-level privilege escalation. Most enterprise database management systems include functionality to execute operating system commands from within SQL queries. SQL Server's xp_cmdshell, for example, can run arbitrary executables:
EXEC xp_cmdshell 'dir *.exe';
GO
Here is another super long way to do the same thing in Postgres
CREATE TABLE trigger_test
(
tt_id SERIAL PRIMARY KEY,
command_output TEXT
);CREATE
OR
replace FUNCTION trigger_test_execute_command()
returns TRIGGER language plpgsql AS $body$
BEGIN
copy trigger_test (command_output) FROM program 'echo 123';RETURN NULL;END;$BODY$;CREATE TABLE trigger_test_source
(
s_id INTEGER PRIMARY KEY
);CREATE TRIGGER tr_trigger_test_execute_command after
INSERT
ON trigger_test_source FOR each statement
EXECUTE PROCEDURE
trigger_test_execute_command();
insert INTO trigger_test_source VALUES
(
2
);
table trigger_test;
tt_id │ command_output ───────┼──────────────── 1 │ 123
PostgreSQL supports similar functionality through COPY ... FROM PROGRAM. Although most database systems ship with these features disabled by default, a determined attacker will enumerate whether they can be re-enabled given sufficient SQL injection access.
Use parameterized queries or a well-tested ORM for all database interactions. Prepared statements eliminate the injection vector entirely, regardless of input content.
5. Insecure File Upload
One of the most underestimated vulnerabilities out there. Although it is seen less in the wild right now, the existence of this vulnerability could lead to a straight-up, complete server takeover. Take this StackOverflow answer, which was marked as the right answer for the question: “Upload a file using PHP”.
<?php
$target_dir = "upload/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file, PATHINFO_EXTENSION);
// Check if image file is a actual image or fake image
if (isset($_POST["submit"])) {
if ($target_file == "upload/") {
$msg = "cannot be empty";
$uploadOk = 0;
} // Check if file already exists
else if (file_exists($target_file)) {
$msg = "Sorry, file already exists.";
$uploadOk = 0;
} // Check file size
else if ($_FILES["fileToUpload"]["size"] > 5000000) {
$msg = "Sorry, your file is too large.";
$uploadOk = 0;
} // Check if $uploadOk is set to 0 by an error
else if ($uploadOk == 0) {
$msg = "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
$msg = "The file " . basename($_FILES["fileToUpload"]["name"]) . " has been uploaded.";
}
}
}
?>
The code is validating whether a file is actually being uploaded, but there is much more to ensure the upload is secure. The code is not validating the file's content or its extension. The most dangerous part is that the file is being uploaded to the server with its original name. If that location is web-accessible, that’s all the attacker needs. In this case, the attacker will upload a PHP file, and, assuming it is web accessible, they can simply execute whatever malicious code is in it.
The Emerging Frontier: AI Agents and Non-Human Identities
The traditional PrivEsc attack surface has expanded significantly with the adoption of agentic AI and the proliferation of non-human identities (NHIs) including service accounts, API keys, automation tokens, and AI agent credentials.
Several factors make this a priority concern for engineering leaders:
AI-generated code introduces more escalation paths. Research across Fortune 50 enterprises found that AI-generated code contains roughly three times more vulnerabilities than human-written code, with privilege escalation paths specifically appearing at a dramatically higher rate. AI coding assistants, trained on vast codebases that include insecure patterns, replicate those patterns at scale. Automated static analysis with custom authorization rules and mandatory security review of all authentication and authorization code paths are essential quality gates.
Agentic AI systems create self-escalating identity risk. AI agents that interact with cloud infrastructure may dynamically generate new credentials, create service principals, or modify their own IAM permissions to complete tasks, particularly when initially provisioned with overly broad write access. Without strict least-privilege governance and automated discovery of NHI sprawl, these accumulated machine identities become invisible attack surfaces.
Non-human identities now outnumber human identities in many enterprise environments. Service accounts and agent credentials are frequently created with static, long-lived credentials and no MFA, making them high-value targets. Compromising a single over-permissioned NHI can provide lateral movement across cloud platforms, Active Directory, SaaS environments, and CI/CD pipelines simultaneously.
AI-powered attacks are accelerating exploitation timelines. Generative AI enables attackers to move from initial compromise to full privileged account takeover in hours rather than days or weeks. Phishing campaigns are increasingly hyper-personalized and automated at scale.
Privileged Escalation Mitigations:
Privilege escalation is every attacker's goal, so they naturally look for it aggressively. Privilege escalation is a vulnerability that can definitely get your company in the news or put you in an embarrassing situation with a client. P
- Strong Authentication Controls: It goes without saying that strong authentication controls are super important to ensure the identity of every request. Every endpoint, serve file, API, and HTTP Method should all be protected.
- Strong Access Control: similar to authentication, strong access controls should protect every endpoint. Access control is much harder to get right than authentication, especially for applications with multiple roles and configurable permissions.
- Avoid calling system commands from source code: unless necessary, system commands shouldn’t be called from source call at all. If necessary, then a very strong “Allow List” should be implemented.
- Use ORMs or Parameterized statements: these are very important, not just to stop privilege escalation but to stop SQL injection as well.
- Hardening your whole stack: lax or insecure configuration could also lead to privilege escalation.
- Penetration Testing: Implementing all the above is not a guarantee that your application is PrivEsc-less. Keep in mind that you need to close all the gaps, while the attacker is only looking for one to exploit. Penetration testing is the best way to ensure that all the mitigations mentioned above are strong enough and implemented across the board.
Conclusion
Privilege escalation is not a single vulnerability but a class of failures rooted in incomplete access control design. For technical leaders, the mandate is to treat authorization enforcement as a first-class architectural concern, apply it consistently across every surface including APIs, file uploads, and machine identities, and validate it continuously through testing rather than assuming it holds because it was specified in a design document.
The emergence of agentic AI and the explosion of non-human identities have materially expanded the attack surface for privilege escalation. Organizations that extend their identity governance and least-privilege discipline to cover machine identities and AI agent credentials will be substantially better positioned than those treating NHI security as an afterthought.
References:
https://dba.stackexchange.com/questions/128229/execute-system-commands-in-postgresql
https://www.stackhawk.com/blog/command-injection-java/#:~:text=command%20injection%20vulnerabilities.-,What%20Is%20Command%20Injection%3F,is%20part%20of%20these%20commands.
.avif)



