Missing Authorization
Missing Authorization
What it is
CWE-862 exists when an application confirms a requester is authenticated but does not check that the requester is authorized to perform the specific action on the specific resource. The endpoint trusts that any authenticated user is also authorized, which fails as soon as any privileged operation or any per-user data is involved.
Why it matters
Missing authorization is the dominant pattern behind Insecure Direct Object Reference (IDOR), the data class that has caused some of the largest single breaches in disclosed history (US Treasury, Optus, T-Mobile). It is hard to find via automated scanning alone because the code does check authentication: tools have to understand the data model and the relationship between request parameters and ownership. Modern application security practice consolidates authorization at a policy layer (OPA, Cedar, Casbin) rather than scattering checks across handlers.
Common patterns
- •GET /api/<resource>/:id where the handler fetches by id without filtering by the authenticated user.
- •PUT/DELETE endpoints that authenticate the caller but accept the target resource id without ownership verification.
- •GraphQL resolvers that authorize at the query root but not at nested field resolvers.
- •File-download endpoints that issue a signed URL or stream content without re-checking ownership.
- •Background-job triggers that any authenticated user can enqueue, allowing privileged actions through a queue worker.
- •Search endpoints that index across tenants and rely on UI filtering for tenant scoping.
Languages affected
What Deva detects
Deva's authorization rule pack identifies handlers that take a resource id as a path or query parameter, fetch the resource from the database, and return it without an ownership predicate. The scanner traces data flow from request inputs to ORM calls and reports findings when the .where / filter / scope chain lacks an authenticated-user constraint. False positives (handlers where any authenticated user is legitimately allowed to read the resource) can be suppressed with an inline comment.
Example
Vulnerable
@app.delete('/api/documents/<doc_id>')
@require_auth
def delete_document(doc_id):
doc = Document.query.get_or_404(doc_id)
db.session.delete(doc)
db.session.commit()
return jsonify({'ok': True})Fixed
@app.delete('/api/documents/<doc_id>')
@require_auth
def delete_document(doc_id):
# Filter by both the document id and the authenticated user's ownership.
doc = Document.query.filter_by(id=doc_id, owner_id=current_user.id).first_or_404()
db.session.delete(doc)
db.session.commit()
audit_log.write(actor=current_user.id, action='delete_document', target=doc_id)
return jsonify({'ok': True})Explanation
The vulnerable version confirms a user is signed in but accepts any document id and deletes it. Any authenticated user can delete any user's documents. The fix scopes the query by owner_id = current_user.id and returns 404 (the same code as not-found) when the document does not belong to the caller. Returning identical 404 responses for not-found and not-authorized prevents enumeration of valid document ids. For shared documents, the query should look up an access-grant row rather than a direct owner match.
Where this fits in OWASP Top 10
Compliance framework mapping
| Framework | Controls |
|---|---|
| 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-862 alongside 970+ other CWE patterns at write time, with AI-assisted fix generation that maintains compliance.