CWE-287HighMITRE entry

Improper Authentication

Improper Authentication

What it is

CWE-287 covers a family of weaknesses where an application fails to correctly verify the identity of an entity (user, service, device) that interacts with it. Variants include missing authentication for critical functions, broken authentication logic, weak credentials, predictable session identifiers, and authentication bypass via parameter manipulation.

Why it matters

Improper authentication maps directly to account takeover, lateral movement, and total compromise. It is the foundational weakness behind most disclosed breaches. The OWASP Top 10 elevates Broken Access Control (A01) and Identification and Authentication Failures (A07) into the top tier for this reason. HIPAA, PCI-DSS, and CMMC all impose explicit authentication-control requirements that map to this CWE.

Common patterns

  • Authentication checks that only happen client-side (the API doesn't re-verify).
  • Password comparison via == (timing-attackable) instead of constant-time comparison.
  • Session IDs generated from predictable sources (timestamps, counters, weak PRNG).
  • Token validation that decodes JWTs but does not verify the signature.
  • Routes that check 'logged in' without checking 'authorized for this resource'.
  • Backdoor or debug routes left enabled in production.

Languages affected

PythonJavaScriptTypeScriptJavaGoRubyPHPC#

What Deva detects

Deva includes a suite of authentication-specific rules: detection of password comparison without constant-time helpers (use crypto.timingSafeEqual, secrets.compare_digest), JWT verify calls with verify: false or with no signing key, missing requireAuth middleware before sensitive route handlers, session ID generation with Math.random or other weak sources, and hardcoded credentials in code or configs (CWE-798 overlap).

Example

Vulnerable

app.post('/transfer', async (req, res) => {
  const { fromAccount, toAccount, amount } = req.body
  await db.transfer(fromAccount, toAccount, amount)
  res.json({ ok: true })
})

Fixed

app.post('/transfer', requireAuth, async (req, res) => {
  const { toAccount, amount } = req.body
  const userId = req.user.id
  const fromAccount = await db.getAccountForUser(userId)
  if (!fromAccount) return res.status(403).json({ error: 'No account' })
  await db.transfer(fromAccount.id, toAccount, amount)
  res.json({ ok: true })
})

Explanation

The vulnerable version has no authentication middleware and accepts fromAccount as a request parameter. Any caller can transfer from any account. The fix gates the route on requireAuth, derives the fromAccount from the authenticated user's identity rather than from request input, and confirms ownership before executing the transfer.

Where this fits in OWASP Top 10

Compliance framework mapping

FrameworkControls
OWASP Top 10 (2021)
A01:2021 Broken Access ControlA07:2021 Identification and Authentication Failures
NIST 800-53 Rev 5
IA-2 Identification and AuthenticationAC-3 Access Enforcement
PCI-DSS v4.0
8.3 Strong authentication
HIPAA Security Rule
164.312(d) Person or Entity Authentication
CMMC 2.0 L2
IA.L2-3.5.1 Identify users

Related CWEs

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