# Authorization Bypass Through User-Controlled Key (CWE-639) The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data. **Stack:** JavaScript - Prevalence: High Frequently exploited - Impact: Critical 1 critical-severity rules - Prevention: Documented 8 fix examples **OWASP:** Broken Access Control (A01:2021-Broken Access Control) - #1 ## Description Retrieval of a user record usually occurs in the system based on some key value. When a value that is directly specified by the user is used to look up that record, the key value can be modified to access records belonging to other users. ## Prevention Prevention strategies for Authorization Bypass via User Key based on 3 Shoulder detection rules. ### JavaScript Filter queries by authenticated user ID to verify resource ownership Include userId in database queries to verify resource ownership before access Verify resource ownership before returning data by checking it belongs to the authenticated user ## Warning Signs - [HIGH] when user-controlled input (from URL parameters, query strings, or request body) is used directly to - [MEDIUM] endpoints where route parameters flow to generic data access patterns (Map - [CRITICAL] when user-controlled input is used to access resources belonging to other users at the same privileg ## Consequences - Read Application Data - Modify Application Data - Gain Privileges ## Mitigations - Use indirect references (mapping) rather than direct database keys - Validate that the current user has permission to access the requested resource - Implement proper access control checks on every request ## Detection - Total rules: 8 - Critical: 1 - Languages: go, javascript, typescript, python ## Rules by Language ### Javascript (3 rules) - **Horizontal Privilege Escalation** [CRITICAL]: Detects when user-controlled input is used to access resources belonging to other users at the same privilege level without verifying ownership. - Remediation: Filter queries by authenticated user ID to verify ownership. ```javascript const profile = await User.findOne({ where: { id: req.params.userId, userId: req.user.id } }); ``` Learn more: https://shoulder.dev/learn/javascript/cwe-639/horizontal-privilege-escalation - **Insecure Direct Object Reference (IDOR)** [HIGH]: Detects when user-controlled input (from URL parameters, query strings, or request body) is used directly to access database records without verifying that the authenticated user has permission to access that specific resource. IDOR vulnerabilities allow attackers to access, modify, or delete resources belonging to other users by manipulating identifiers in requests. - Remediation: Include userId in queries to verify resource ownership before access. ```javascript const order = await Order.findOne({ where: { id: req.params.id, userId: req.user.id } }); ``` Learn more: https://shoulder.dev/learn/javascript/cwe-639/idor - **Potential IDOR - Generic Data Access** [MEDIUM]: Detects endpoints where route parameters flow to generic data access patterns (Map.get, object property access, cache lookups, custom repositories) without visible ownership verification in the function. This rule catches patterns that ORM-specific detection misses, but requires human verification that authorization is not enforced elsewhere (middleware, decorators, API gateway, etc.). **This is a "potential" finding - verify authorization exists somewhere.** - Remediation: Verify ownership before returning data by checking resource belongs to authenticated user. ```javascript const order = orders.get(req.params.id); if (order.userId !== req.user.id) { return res.status(403).json({ error: 'Forbidden' }); } ``` Learn more: https://shoulder.dev/learn/javascript/cwe-639/idor-generic ### Typescript (3 rules) - **Horizontal Privilege Escalation** [CRITICAL]: Detects when user-controlled input is used to access resources belonging to other users at the same privilege level without verifying ownership. - Remediation: Filter queries by authenticated user ID to verify ownership. ```javascript const profile = await User.findOne({ where: { id: req.params.userId, userId: req.user.id } }); ``` Learn more: https://shoulder.dev/learn/javascript/cwe-639/horizontal-privilege-escalation - **Insecure Direct Object Reference (IDOR)** [HIGH]: Detects when user-controlled input (from URL parameters, query strings, or request body) is used directly to access database records without verifying that the authenticated user has permission to access that specific resource. IDOR vulnerabilities allow attackers to access, modify, or delete resources belonging to other users by manipulating identifiers in requests. - Remediation: Include userId in queries to verify resource ownership before access. ```javascript const order = await Order.findOne({ where: { id: req.params.id, userId: req.user.id } }); ``` Learn more: https://shoulder.dev/learn/javascript/cwe-639/idor - **Potential IDOR - Generic Data Access** [MEDIUM]: Detects endpoints where route parameters flow to generic data access patterns (Map.get, object property access, cache lookups, custom repositories) without visible ownership verification in the function. This rule catches patterns that ORM-specific detection misses, but requires human verification that authorization is not enforced elsewhere (middleware, decorators, API gateway, etc.). **This is a "potential" finding - verify authorization exists somewhere.** - Remediation: Verify ownership before returning data by checking resource belongs to authenticated user. ```javascript const order = orders.get(req.params.id); if (order.userId !== req.user.id) { return res.status(403).json({ error: 'Forbidden' }); } ``` Learn more: https://shoulder.dev/learn/javascript/cwe-639/idor-generic