CWE-266, Incorrect Privilege Assignment, is a product that assigns a privilege to the wrong actor, creating an unintended sphere of control for that actor.
It hits anyone who writes installers, provisioning tools, admin consoles, or permission models. The flaw is not in a check that fails. The check works fine. The wrong thing was granted in the first place.
How it happens
Privilege assignment goes wrong in a few recurring ways, all visible in MITRE's observed examples:
- A default grants too much. CVE-1999-1193 (Gold) is an untrusted user placed in the Unix wheel group.
- Users can grant rights to themselves. CVE-2005-2741 (Gold) is a product that allows users to grant themselves certain rights, which can be used to escalate privileges.
- The wrong identifier is used. CVE-2005-2496 (Gold) uses the group ID of a user instead of the group, so the program runs with different privileges.
- A status is assigned by mistake. CVE-2004-0274 (Gold) mistakenly assigns a particular status to an entity, leading to increased privileges.
A web application version looks like this:
# Vulnerable: trusts a role sent by the client
@app.post("/signup")
def signup():
user = User(email=request.form["email"],
role=request.form.get("role", "member"))
db.add(user)
Anyone can post role=admin.
What an attacker gains
MITRE lists gaining privileges or assuming identity. A user can reach restricted functionality and sensitive information, which may include administrative functions and other user accounts.
How to find it
- Review every place that writes a role, group, or permission, and ask who is allowed to call it.
- Diff the privileges of a brand new account against what the role is meant to have.
- Search for code that copies request parameters into privilege fields.
- Check installer scripts for default group memberships.
How to fix it
Decide privileges on the server from a trusted source, never from user supplied input.
@app.post("/signup")
def signup():
user = User(email=request.form["email"], role="member")
db.add(user)
- Start every new account at the lowest privilege.
- Separate the right to use a feature from the right to grant access to it.
- Log every privilege change and review the log.
- Test with a fresh account as part of your regular checks.
Quick check
Why is accepting a role field from a form a CWE-266 problem?
The server hands out a privilege based on a value the requester controls. The assignment is wrong even though no access check was bypassed.
Sources
- MITRE CWE-266: https://cwe.mitre.org/data/definitions/266.html
- Safeguard Gold entry: https://gold.safeguard.sh/cwe/CWE-266