CWE-264 describes weaknesses in how applications manage who can do what — the rules that decide whether a user, process, or system component is allowed to…
CWE-264 describes weaknesses in how applications manage who can do what — the rules that decide whether a user, process, or system component is allowed to access a resource or perform an action. When these controls are broken, misconfigured, or missing, attackers can bypass intended restrictions, access data they shouldn't see, modify things they shouldn't touch, or escalate their privileges to administrator level.
02How It Happens
Access control failures stem from several common patterns: hardcoded assumptions about user roles, missing permission checks before sensitive operations, inconsistent enforcement across different code paths, or reliance on client-side validation alone. Developers may forget to verify permissions on every request, assume that hiding a feature in the UI is enough to protect it, or fail to re-authenticate before high-risk actions. Role-based access control (RBAC) systems can also fail if roles are assigned incorrectly, if privilege inheritance is not properly scoped, or if default permissions are too permissive.
03Real-World Impact
Broken access controls allow attackers to view confidential files, modify or delete records belonging to other users, perform administrative actions without authorization, or escalate from a low-privilege account to full system control. A user might access another user's profile, change payment information, read private messages, or disable security features. In multi-tenant systems, one customer's data can leak to another. The impact ranges from privacy violations and data theft to complete compromise of the application and its underlying infrastructure.
04Vulnerable & Fixed Patterns
Vulnerable pattern
@app.route('/user/<user_id>/profile')
def get_user_profile(user_id):
# No check that current_user is authorized to view this profile
user = db.query(User).filter(User.id == user_id).first()
return jsonify(user.to_dict())
@app.route('/admin/delete_user', methods=['POST'])
def delete_user():
# No verification that current_user is an admin
user_id = request.form.get('user_id')
db.query(User).filter(User.id == user_id).delete()
db.commit()
return "User deleted"
Why it's vulnerable: The first endpoint returns any user's profile without checking whether the requesting user has permission to view it. The second endpoint performs a destructive admin action without verifying the caller's role, allowing any authenticated user to delete accounts.
Fixed pattern
from functools import wraps
def require_permission(permission):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.has_permission(permission):
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator
@app.route('/user/<user_id>/profile')
@require_permission('view_profile')
def get_user_profile(user_id):
# Verify ownership or explicit permission
if current_user.id != user_id and not current_user.is_admin():
abort(403)
user = db.query(User).filter(User.id == user_id).first()
return jsonify(user.to_dict())
@app.route('/admin/delete_user', methods=['POST'])
@require_permission('admin')
def delete_user():
user_id = request.form.get('user_id')
db.query(User).filter(User.id == user_id).delete()
db.commit()
return "User deleted"
Vulnerable pattern
<?php
// Assume $_SESSION['user_id'] and $_SESSION['role'] are set
// Endpoint to view user data
if ($_GET['action'] === 'view_user') {
$user_id = $_GET['user_id'];
$user = $wpdb->get_row("SELECT * FROM users WHERE id = $user_id");
echo json_encode($user);
}
// Endpoint to delete a user (admin only)
if ($_GET['action'] === 'delete_user') {
$user_id = $_GET['user_id'];
$wpdb->query("DELETE FROM users WHERE id = $user_id");
echo "User deleted";
}
?>
Why it's vulnerable: The view_user endpoint returns any user's data without checking if the current user is authorized. The delete_user endpoint performs an admin action without verifying the user's role, allowing any logged-in user to delete accounts.
Fixed pattern
<?php
function check_permission($required_role) {
if (!isset($_SESSION['role']) || $_SESSION['role'] !== $required_role) {
wp_die('Access denied', 'Forbidden', array('response' => 403));
}
}
function user_can_view($target_user_id) {
return $_SESSION['user_id'] == $target_user_id || $_SESSION['role'] === 'admin';
}
if ($_GET['action'] === 'view_user') {
$user_id = intval($_GET['user_id']);
if (!user_can_view($user_id)) {
wp_die('Access denied', 'Forbidden', array('response' => 403));
}
$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM users WHERE id = %d", $user_id));
echo json_encode($user);
}
if ($_GET['action'] === 'delete_user') {
check_permission('admin');
$user_id = intval($_GET['user_id']);
$wpdb->query($wpdb->prepare("DELETE FROM users WHERE id = %d", $user_id));
echo "User deleted";
}
?>
05Prevention Checklist
Check permissions on every request. Do not rely on UI hiding or client-side validation; verify authorization server-side before every sensitive operation.
Use a consistent access control model. Implement role-based access control (RBAC) or attribute-based access control (ABAC) consistently across all endpoints and code paths.
Default to deny. Assume users have no access unless explicitly granted; avoid overly permissive defaults.
Verify ownership and role together. When a user requests their own data, still verify their identity; when they request admin actions, verify their role.
Log and monitor access attempts. Record failed authorization checks and unusual access patterns to detect abuse.
Test access controls thoroughly. Include test cases that verify a low-privilege user cannot access high-privilege resources, and that users cannot access other users' data.
06Signs You May Already Be Affected
Look for unexpected admin accounts you did not create, users reporting access to data or features they should not have, or log entries showing failed permission checks followed by successful operations. If you can access another user's profile by changing a URL parameter, or if you can perform admin actions without being an administrator, your access controls are broken.