Safeguard
Application Security•

CWE-284 Improper Access Control: The Pillar Behind Many Breaches

CWE-284 is the top level weakness for failing to restrict access to a resource. Learn the specification versus enforcement split, real CVEs, and a review method.

Safeguard Security Team
5 min read

CWE-284, Improper Access Control, is a product that does not restrict, or incorrectly restricts, access to a resource from an unauthorized actor.

MITRE classifies it as a pillar, the highest level of abstraction in the CWE hierarchy. Dozens of narrower weaknesses descend from it, including improper authorization (CWE-285), improper authentication (CWE-287), privilege problems, and permission problems. If you want one concept that explains a large share of breaches, this is it.

It affects every kind of software: web applications, APIs, operating systems, databases, embedded and industrial devices. MITRE lists web based and ICS and OT technologies among the relevant platforms.

How it happens

MITRE describes access control as several protection mechanisms working together:

  • Authentication. Proving the identity of an actor.
  • Authorization. Ensuring that a given actor can access a resource.
  • Accountability. Tracking the activities that were performed.

When any one of them is missing or fails, attackers can gain privileges, read sensitive information, execute commands, or evade detection.

MITRE also separates two distinct ways to introduce access control weaknesses:

Specification. Incorrect privileges, permissions, or ownership are explicitly set for the user or the resource. Examples from MITRE: setting a password file to be world-writable, or giving administrator capabilities to a guest user. This can be done by the program or by an administrator.

Enforcement. The mechanism contains errors that prevent it from properly enforcing the specified access control requirements. For example, a rule exists but the code applies it inconsistently.

That split is useful in review. When you find a problem, ask first whether the rule is wrong or the enforcement is wrong. The fix differs.

Real examples from MITRE's record show enforcement failures of several kinds:

  • CVE-2022-24985 (Gold): a form hosting website checks the session authentication status for only a single form, making it possible to bypass authentication when there are multiple forms.
  • CVE-2022-29238 (Gold): an access control setting in a web based document collaboration tool is not implemented correctly by the code, which prevents listing hidden directories but does not prevent direct requests to files in those directories.
  • CVE-2022-23607 (Gold): a Python based HTTP library did not scope cookies to a particular domain, so "supercookies" could be sent to any domain on redirect.
  • CVE-2023-26463 (Gold): MITRE describes a chain in which an IPSec VPN product uses the same variable for multiple purposes in the same function, leading to incorrect access control and an expired pointer dereference.

The second one illustrates a common pattern. The developer hid the listing and assumed that was protection. The files were still reachable by direct request.

Here is a minimal version of that pattern:

# Vulnerable: hides the link, does not protect the file
@app.get("/reports")
def list_reports():
    return [r.name for r in reports_visible_to(current_user)]

@app.get("/reports/<name>")
def get_report(name):
    return send_file(f"reports/{name}")   # no check at all

What an attacker gains

MITRE lists the consequence as varying by context. That is accurate, because the pillar covers so much. Depending on the resource, an attacker may read sensitive data, change data, run commands, gain higher privileges, or hide what they did.

A single missing check can open an entire feature. Because access control failures are so direct, with no clever exploit needed, they tend to be found quickly once a determined person starts looking.

How to find it

A good access control review is mostly systematic enumeration:

  1. List every resource and every action. Endpoints, files, records, admin functions, background jobs.
  2. List every actor type. Anonymous, regular user, other tenant, support staff, administrator, service account.
  3. Build the matrix. For each pair, write down whether access should be allowed.
  4. Test the denials. Try to do what should be refused, using a different account and directly crafted requests, not only the UI.
  5. Look for direct paths. Request the resource by its URL, ID, or path without going through the page that links to it.
  6. Check consistency. If one endpoint has a check, confirm its siblings do too. CVE-2022-24985 above is exactly this failure.
  7. Review defaults. What happens to a new route, a new file, a new role if nobody adds a rule?

Automated tools help with the enumeration but not with the judgment of what should be allowed. Static analysis can spot missing checks on known frameworks. Dynamic scanners find unauthenticated interfaces. People decide whether a given exposure is intended.

How to fix it

  • Deny by default. Access is refused unless a rule explicitly grants it.
  • Enforce on the server, at the resource. Put the check where the data is served, not only in the interface that links to it.
  • Centralize. Use one policy layer, middleware, or framework feature, instead of ad hoc checks that drift apart.
  • Apply least privilege. Give users, roles, and services the minimum they need.
  • Check on every request. Do not cache an allow decision past the point where it could change.
  • Fix both halves. Correct the specification, meaning who should have what, and the enforcement, meaning that the code applies it.
  • Log and review. Record access to sensitive resources and denied attempts.

The earlier example, fixed:

@app.get("/reports/<name>")
def get_report(name):
    report = Report.query.filter_by(name=name).first_or_404()
    if not can_view(current_user, report):
        abort(403)
    return send_file(report.path)

Quick check

What is the difference between a specification and an enforcement weakness?

A specification weakness means the wrong access was defined, such as a world-writable password file or admin rights for a guest. An enforcement weakness means the right rule exists but the code fails to apply it correctly.

Why is hiding a link not access control?

The resource is still reachable by a direct request. Only a server side check at the resource itself restricts access.

Why is CWE-284 called a pillar?

It sits at the top of MITRE's hierarchy as a broad concept, with many more specific weaknesses descending from it.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.