Sql Injection with Api Keys
How SQL Injection Manifests in API Keys
SQL injection in API keys occurs when attackers manipulate API key parameters to inject malicious SQL code into database queries. This vulnerability typically appears in API endpoints that accept API keys as query parameters or headers and use them directly in SQL statements without proper sanitization.
A common pattern is API endpoints that validate API keys by querying a database:
// Vulnerable API key validation
const apiKey = req.query.apiKey;
const query = `SELECT * FROM users WHERE api_key = '${apiKey}'`;
An attacker can exploit this by submitting an API key like:
apiKey=validKey' OR '1'='1
This transforms the query into:
SELECT * FROM users WHERE api_key = 'validKey' OR '1'='1'
The OR '1'='1' condition always evaluates to true, potentially bypassing authentication entirely. More sophisticated attacks can extract data, modify records, or even drop tables.
API keys are particularly vulnerable because they're often treated as opaque strings rather than user input. Attackers know that API keys are typically stored in database tables, making them attractive targets for injection. The stateless nature of API keys means attackers can repeatedly test different injection payloads without triggering traditional account lockout mechanisms.
Real-world examples include CVE-2021-3178 where API key parameters were directly concatenated into SQL queries, allowing attackers to extract sensitive user data from e-commerce platforms.
API Keys-Specific Detection
Detecting SQL injection in API keys requires both static analysis and dynamic testing. Static analysis tools can identify code patterns where API keys are directly interpolated into SQL strings. Dynamic testing involves submitting malicious payloads to API endpoints and observing database responses.
middleBrick's API security scanner specifically tests API key parameters for SQL injection vulnerabilities. The scanner submits payloads like:
' OR 1=1--
' OR 'a'='a
admin' --
and analyzes responses for signs of successful injection, such as:
- Unexpected data in responses (indicating query manipulation)
- Authentication bypass (returning user data without valid API key)
- Database error messages (revealing SQL syntax)
- Timing differences (indicating conditional logic execution)
middleBrick's scanner also checks for API keys in SQL injection-prone locations: query parameters, headers, and request bodies. The tool's LLM security module can detect if API key validation logic is exposed in system prompts or documentation.
For OpenAPI specification analysis, middleBrick cross-references API key parameters in your spec with runtime findings. If your spec defines an API key parameter but the endpoint is vulnerable to injection, you'll receive a prioritized finding with severity and remediation guidance.
Automated scanning should be part of your CI/CD pipeline. The middleBrick GitHub Action can scan staging APIs before deployment, failing builds if SQL injection vulnerabilities are detected in API key handling.
API Keys-Specific Remediation
Remediation for SQL injection in API keys centers on proper query parameterization and input validation. The most effective approach is using prepared statements with parameterized queries:
// Secure API key validation using parameterized queries
const apiKey = req.query.apiKey;
const query = 'SELECT * FROM users WHERE api_key = ?';
const [results] = await db.query(query, [apiKey]);
This approach ensures the API key is treated as data, not executable SQL code. The database driver handles proper escaping and type validation.
Additional API keys-specific protections include:
- API key format validation: Validate API key format before database queries using regex patterns specific to your key generation scheme
- Rate limiting: Implement rate limiting on API key validation endpoints to slow down automated injection attempts
- API key storage: Store hashed API keys using bcrypt or similar algorithms rather than plain text
- Query whitelisting: Use ORM frameworks that automatically parameterize queries
Here's a complete example using Node.js and MySQL:
const express = require('express');
const mysql = require('mysql2/promise');
const app = express();
const db = mysql.createPool({...});
app.get('/api/data', async (req, res) => {
const apiKey = req.headers['x-api-key'];
// Validate API key format
if (!/^[A-Za-z0-9]{32}$/.test(apiKey)) {
return res.status(400).json({error: 'Invalid API key format'});
}
try {
const [rows] = await db.execute(
'SELECT * FROM users WHERE api_key = ? AND active = 1',
[apiKey]
);
if (rows.length === 0) {
return res.status(401).json({error: 'Invalid API key'});
}
// API key is valid, proceed with request
res.json({data: 'Authorized response'});
} catch (err) {
console.error('Database error:', err);
res.status(500).json({error: 'Internal server error'});
}
});
For languages like Python with SQLAlchemy:
from sqlalchemy import text
def validate_api_key(api_key):
if not re.match(r'^[A-Za-z0-9]{32}$', api_key):
return False
query = text("SELECT * FROM users WHERE api_key = :key AND active = 1")
result = db.execute(query, {'key': api_key}).fetchone()
return result is not None
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 |