Sql Injection in Express with Bearer Tokens
Sql Injection in Express with Bearer Tokens — how this specific combination creates or exposes the vulnerability
SQL Injection in an Express API that uses Bearer Tokens can occur when user-controlled data from an authenticated request is interpolated into SQL queries without proper validation or parameterization. Even when access is protected by token-based authentication, a vulnerable endpoint remains exploitable if it directly concatenates request input (e.g., route parameters, query strings, or body fields) into SQL strings.
Consider an endpoint that retrieves a user profile by ID and expects a Bearer Token in the Authorization header. If the implementation extracts an identifier from the token (such as a user ID) and uses it unsafely in a query, an attacker who obtains or guesses a valid token can still leverage injection if the endpoint is poorly coded. For example, using string concatenation to build queries exposes the attack surface regardless of the token mechanism:
const userId = req.user.id; // from Bearer token verification
const query = 'SELECT * FROM users WHERE id = ' + userId;
const result = await db.query(query);
Here, even though the request includes a Bearer Token and the caller is authenticated, the SQL string is constructed dynamically. An attacker could manipulate the user ID or any other input used downstream to change the query logic, bypassing intended data boundaries. Common patterns include using extracted token claims to locate resources and then failing to enforce strict authorization checks at the data layer, leading to unauthorized data access or privilege escalation.
The interaction with Bearer Tokens becomes especially relevant when token payloads include roles or scopes that the application trusts without additional validation. If the server uses role information from the token to decide what data to query but still builds queries using unchecked input, the combination can lead to Insecure Direct Object References (IDOR) or BOLA alongside SQL Injection. For instance, an attacker with a low-privilege token might manipulate parameters to access or modify data belonging to other users because the query does not enforce tenant or ownership constraints.
Moreover, if token verification middleware is misconfigured or skipped on certain routes, unauthenticated attackers might probe endpoints that rely on token-derived identifiers. Even when authentication is enforced, malformed or overly permissive token handling can result in ambiguous identity context, making it harder to trace whether a given SQL statement should be constrained by the token subject. This increases the risk of inadvertently exposing or corrupting data through injection.
Real-world attack patterns such as authentication bypass via SQL Injection (CVE-2019-19855) or privilege escalation through union-based techniques highlight the importance of treating authenticated inputs as untrusted. middleBrick’s LLM/AI Security checks and 12 parallel scans (including Authentication, BOLA/IDOR, and Input Validation) help detect these risky combinations by correlating runtime behavior with OpenAPI specifications and known attack vectors.
Bearer Tokens-Specific Remediation in Express — concrete code fixes
Remediation focuses on strict input validation, parameterized queries, and ensuring token-derived data does not bypass SQL safety. Never trust claims from a Bearer Token when building SQL; treat them as part of the request context and enforce authorization checks at the query level.
Use parameterized queries or prepared statements to ensure user input is never interpreted as executable SQL. For example, with the mysql2 library:
const mysql = require('mysql2/promise');
const connection = await mysql.createConnection({ database: 'app' });
app.get('/profile/:id', async (req, res) => {
const tokenUserId = req.user.id; // from Bearer token verification
const requestedId = req.params.id;
// Enforce ownership: ensure token user can only access their own profile
if (tokenUserId !== requestedId) {
return res.status(403).json({ error: 'Forbidden' });
}
const [rows] = await connection.execute(
'SELECT id, name, email FROM users WHERE id = ?',
[requestedId]
);
res.json(rows[0] || {});
});
If using an ORM, configure it to use parameterized conditions and avoid raw query concatenation. With an ORM like Sequelize, prefer its built-in mechanisms:
const { User } = require('./models');
app.get('/profile/:id', async (req, res) => {
const tokenUserId = req.user.id;
const requestedId = req.params.id;
if (tokenUserId !== requestedId) {
return res.status(403).json({ error: 'Forbidden' });
}
const user = await User.findByPk(requestedId, {
attributes: { exclude: ['password'] }
});
res.json(user || {});
});
Additionally, validate and sanitize all inputs. For numeric IDs, enforce strict type checks before using them in queries:
const id = parseInt(req.params.id, 10);
if (isNaN(id)) {
return res.status(400).json({ error: 'Invalid ID' });
}
Apply the same principle when handling filters or search parameters extracted from the request. Combine these practices with middleware that verifies Bearer Tokens and attaches a normalized identity to req.user, ensuring consistent access control across routes.
middleBrick’s CLI tool (middlebrick scan <url>) and GitHub Action can help identify endpoints where token-derived data is used in database interactions without proper safeguards, supporting continuous monitoring as part of the Pro plan or CI/CD gates.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |