CWE-863HighMITRE entry

Incorrect Authorization

Incorrect Authorization

What it is

CWE-863 exists when an application performs an authorization check that is present but logically wrong: it verifies the wrong principal, checks the wrong resource, uses OR where AND is required, or relies on a token that the requester controls. The result is broken access control with a check that looked correct in review.

Why it matters

Incorrect authorization is consistently in the OWASP Top 10 (A01:2021 Broken Access Control). It is harder to detect than missing authorization (CWE-862) because the code does check something. Common manifestations include Insecure Direct Object References (IDOR), tenant-id confusion in multi-tenant systems, and role hierarchies where one role's permissions accidentally include another's. Capital One, Optus, and many other major breaches traced their root cause to incorrect authorization rather than missing authentication.

Common patterns

  • Fetching a resource by a request-supplied ID without checking that the authenticated user owns it (IDOR).
  • Authorization check on req.user but the operation acts on req.params.userId.
  • Role check that uses OR when AND is required (any of these roles vs all of these roles).
  • Tenant scoping via a query parameter rather than via a property of the authenticated identity.
  • GraphQL resolvers that authorize at the query level but not at the field or row level.
  • Cached authorization decisions that do not invalidate when permissions change.

Languages affected

JavaScriptTypeScriptPythonRubyJavaGoPHPC#

What Deva detects

Deva detects route handlers that fetch a resource by a request parameter without a subsequent ownership check. The scanner traces request-parameter values to database query filters and reports when the filter set lacks an authenticated-user constraint. The rule pack also flags ORM patterns where .findById is used without scoping (.findByIdAndUserId), and authorization middlewares whose condition matches any role rather than the required role.

Example

Vulnerable

app.get('/api/orders/:id', requireAuth, async (req, res) => {
  const order = await db.orders.findById(req.params.id)
  if (!order) return res.status(404).json({ error: 'Not found' })
  res.json(order)
})

Fixed

app.get('/api/orders/:id', requireAuth, async (req, res) => {
  const order = await db.orders.findOne({
    where: { id: req.params.id, userId: req.user.id },
  })
  if (!order) return res.status(404).json({ error: 'Not found' })
  res.json(order)
})

Explanation

The vulnerable version authenticates the user (requireAuth confirms a valid session) but does not authorize the resource: any logged-in user can request /api/orders/12345 regardless of who owns order 12345. The fix scopes the query by the authenticated user's id. For systems where multiple users can legitimately view the same resource (admin, customer-service), encode the rule in the where clause, not at the application layer above the query. Returning the same 404 for not-found and not-authorized prevents enumeration.

Where this fits in OWASP Top 10

Compliance framework mapping

FrameworkControls
OWASP Top 10 (2021)
A01:2021 Broken Access Control
NIST 800-53 Rev 5
AC-3 Access EnforcementAC-6 Least Privilege
PCI-DSS v4.0
7.2 Access control system
HIPAA Security Rule
164.312(a)(1) Access Control
CMMC 2.0 L2
AC.L2-3.1.1 Access control policyAC.L2-3.1.2 Limit transactions

Related CWEs

Deva detects CWE-863 alongside 970+ other CWE patterns at write time, with AI-assisted fix generation that maintains compliance.