Improper Privilege Management

Description

Improper Privilege Management occurs when a product does not properly assign, modify, track, or check privileges for actors (users, processes, or systems). This includes failing to restrict access to privileged functionality, not properly validating privilege requirements before performing sensitive operations, and allowing unauthorized privilege escalation. When privilege management is flawed, lower-privileged users can access functionality reserved for administrators, or regular processes can gain system-level access.

Risk

Improper privilege management is a critical vulnerability class that directly enables unauthorized access and privilege escalation. In web applications, flawed role management allows attackers to self-assign administrator roles during registration. In operating systems and databases, improper privilege checks enable users to execute commands as root/Administrator. For critical infrastructure systems, privilege management failures can give attackers full control over industrial processes. This vulnerability consistently enables the most severe attack outcomes: complete system compromise, data breach, and service disruption.

Solution

Implement robust role-based access control (RBAC) with explicit privilege checks for all sensitive operations. Validate privilege requirements server-side; never trust client-provided role information. Use allowlist approaches for privilege assignment—default to minimum access. Audit all privilege-changing operations. Implement separation of duties for critical functions. Regularly review and audit user privileges. Use secure defaults that grant minimal access. Test privilege boundaries through security assessments focusing on authorization bypass.

Common Consequences

ImpactDetails
Access ControlScope: Privilege Escalation

Attackers gain access to administrative functions, enabling complete system control.
IntegrityScope: Data Manipulation

Elevated privileges allow modification of critical data, configurations, and security settings.
ConfidentialityScope: Unauthorized Data Access

Administrative access enables viewing all data including other users' information and system secrets.

Example Code + Solution Code

Vulnerable Code

// VULNERABLE: Role assignment from user input
function register_user($username, $password, $role) {
    // Attacker can pass role='admin' during registration!
    $user = [
        'username' => $username,
        'password' => password_hash($password, PASSWORD_DEFAULT),
        'role' => $role  // User-controlled privilege!
    ];
    save_user($user);
}

// VULNERABLE: Client-side privilege check
function delete_all_users() {
    // Role check happens in JavaScript, not server-side
    // Attacker can call API directly
    $users = get_all_users();
    foreach ($users as $user) {
        delete_user($user['id']);
    }
}
# VULNERABLE: Privilege check based on user-supplied data
@app.route('/admin/users/<id>/delete', methods=['DELETE'])
def delete_user(id):
    # Reads role from session cookie (user-modifiable)
    role = request.cookies.get('role')

    if role == 'admin':  # Attacker can forge cookie
        User.query.filter_by(id=id).delete()
        return 'Deleted'
    return 'Forbidden', 403

# VULNERABLE: Insecure direct object reference + privilege
@app.route('/api/user/<id>/make_admin', methods=['POST'])
def make_admin(id):
    # No check if current user can modify privileges
    user = User.query.get(id)
    user.role = 'admin'
    db.session.commit()
    return 'OK'

Fixed Code

// SAFE: Server-controlled role assignment
function register_user($username, $password) {
    // Role is always set to default, never from user input
    $user = [
        'username' => $username,
        'password' => password_hash($password, PASSWORD_DEFAULT),
        'role' => 'user'  // Always default role
    ];
    save_user($user);
}

// Role can only be elevated by existing admin
function elevate_user_role($admin_id, $target_user_id, $new_role) {
    // Verify admin is actually admin (server-side check)
    $admin = get_user($admin_id);
    if ($admin['role'] !== 'admin') {
        throw new UnauthorizedException();
    }

    // Validate new role is allowed
    if (!in_array($new_role, ['user', 'moderator', 'admin'])) {
        throw new InvalidRoleException();
    }

    // Log privilege change for audit
    audit_log("Role change: {$admin_id} changed {$target_user_id} to {$new_role}");

    update_user_role($target_user_id, $new_role);
}
from functools import wraps

# SAFE: Decorator for privilege verification
def require_admin(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        # Get user from secure session (not cookies)
        user_id = session.get('user_id')
        if not user_id:
            return 'Unauthorized', 401

        # Look up actual role from database
        user = User.query.get(user_id)
        if not user or user.role != 'admin':
            return 'Forbidden', 403

        return f(*args, **kwargs)
    return decorated

@app.route('/admin/users/<id>/delete', methods=['DELETE'])
@require_admin  # Server-side privilege check
def delete_user(id):
    User.query.filter_by(id=id).delete()
    audit_log(f"User {session['user_id']} deleted user {id}")
    return 'Deleted'

@app.route('/api/user/<id>/make_admin', methods=['POST'])
@require_admin
def make_admin(id):
    # Verify requester can elevate privileges
    current_user = User.query.get(session['user_id'])
    if current_user.role != 'super_admin':
        return 'Only super admins can create admins', 403

    user = User.query.get(id)
    user.role = 'admin'
    db.session.commit()
    audit_log(f"Privilege escalation: {current_user.id} made {id} admin")
    return 'OK'

Exploited in the Wild

WordPress Opal Estate Pro (WordPress, 2025)

CVE-2025-6934 (CVSS 9.8 Critical) in WordPress Opal Estate Pro plugin allows unauthenticated attackers to register as administrators due to improper role restriction in the registration process.

Fortinet Products Privilege Escalation (Fortinet, 2025)

CVE-2025-22254 affects FortiOS, FortiProxy, and FortiWeb, allowing authenticated read-only admin users to gain super-admin privileges through crafted websocket requests.

Schneider Electric Saitel DR RTU (Industrial, 2025)

CVE-2025-8453 (CVSS 8.4) allows privileged engineers to escalate to root through improper sudoers configuration in industrial control systems.


Tools to test/exploit

  • Burp Suite — test authorization and privilege boundaries.

  • OWASP ZAP — automated scanning for privilege escalation.

  • AuthMatrix — Burp extension for authorization testing.


CVE Examples


References

  1. MITRE. "CWE-269: Improper Privilege Management." https://cwe.mitre.org/data/definitions/269.html

  2. OWASP. "Access Control." https://owasp.org/www-community/Access_Control