Sql Injection with Basic Auth
How SQL Injection Manifests in Basic Auth
SQL injection in Basic Auth contexts typically occurs when authentication logic constructs database queries using unsanitized username and password inputs. Unlike form-based authentication where SQL injection might target username fields, Basic Auth's credential transmission creates unique injection opportunities.
The most common Basic Auth SQL injection pattern involves the Authorization header containing Base64-encoded credentials. When a server decodes these credentials and directly interpolates them into SQL queries, attackers can manipulate the query structure. For example, a vulnerable implementation might use:
const credentials = Buffer.from(authHeader.split(' ')[1], 'base64').toString().split(':');
const username = credentials[0];
const password = credentials[1];
const query = `SELECT * FROM users WHERE username='${username}' AND password='${password}'`;
An attacker can exploit this by crafting a username like admin' --, which comments out the password check entirely. The resulting query becomes:
SELECT * FROM users WHERE username='admin' --' AND password='anything'
The double-dash comments out the rest of the query, potentially authenticating as the admin user without knowing the password.
Another Basic Auth-specific vector involves timing attacks combined with SQL injection. When authentication fails, the response time might vary based on whether the username exists in the database. An attacker can use this information to enumerate valid usernames, then craft targeted SQL injection payloads for those accounts.
Database-specific injection techniques also apply differently in Basic Auth contexts. MySQL's UNION attacks can extract data from other tables if the initial query structure allows it. PostgreSQL's function calls like pg_sleep() can create timing-based blind injection attacks, useful when error messages are suppressed.
Basic Auth-Specific Detection
Detecting SQL injection in Basic Auth requires understanding both the authentication mechanism and the underlying database queries. The first step is examining how credentials are processed:
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Basic ')) {
return res.status(401).json({ error: 'Missing Basic Auth' });
}
const base64Credentials = authHeader.split(' ')[1];
const credentials = Buffer.from(base64Credentials, 'base64').toString().split(':');
const username = credentials[0];
const password = credentials[1];
Vulnerability indicators include direct string interpolation in SQL queries, lack of prepared statements, and error messages that reveal database structure. A secure implementation would use parameterized queries:
const query = 'SELECT * FROM users WHERE username = ? AND password = ?';
const [user] = await db.query(query, [username, password]);
Automated scanning tools like middleBrick can detect these vulnerabilities by sending crafted Authorization headers with SQL injection payloads and analyzing responses. The scanner tests for common injection patterns such as:
- Single quote termination:
admin' -- - Boolean-based payloads:
admin' AND 1=1 -- - Time-based payloads:
admin' OR sleep(5) AND '1'='1
middleBrick's black-box scanning approach sends these payloads without requiring credentials or access to source code. The tool analyzes response timing, error messages, and authentication outcomes to identify SQL injection vulnerabilities.
Network-level detection also matters. Monitoring for unusual database query patterns, unexpected authentication successes, or timing anomalies can indicate active exploitation attempts. Security Information and Event Management (SIEM) systems should flag Basic Auth endpoints that show signs of injection probing.
Basic Auth-Specific Remediation
Remediation for SQL injection in Basic Auth contexts centers on proper credential handling and query construction. The foundation is using prepared statements or parameterized queries:
// Node.js with MySQL using prepared statements
const mysql = require('mysql2/promise');
const db = mysql.createPool({ host: 'localhost', user: 'app', database: 'app' });
async function authenticate(req, res) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Basic ')) {
return res.status(401).json({ error: 'Missing Basic Auth' });
}
const base64Credentials = authHeader.split(' ')[1];
const credentials = Buffer.from(base64Credentials, 'base64').toString().split(':');
const username = credentials[0];
const password = credentials[1];
const [user] = await db.query(
'SELECT * FROM users WHERE username = ? AND password = ?',
[username, password]
);
if (!user) {
return res.status(401).json({ error: 'Invalid credentials' });
}
res.json({ success: true, user });
}
Beyond query parameterization, implement proper password hashing. Never store or compare plaintext passwords:
// Using bcrypt for password hashing
const bcrypt = require('bcrypt');
async function authenticate(req, res) {
// ... credential extraction
const [user] = await db.query(
'SELECT * FROM users WHERE username = ?',
[username]
);
if (!user) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const passwordMatch = await bcrypt.compare(password, user.password_hash);
if (!passwordMatch) {
return res.status(401).json({ error: 'Invalid credentials' });
}
res.json({ success: true, user });
}
Additional hardening measures include:
- Implement rate limiting on Basic Auth endpoints to slow down automated attacks
- Use consistent response times for both successful and failed authentication attempts
- Log authentication attempts with timestamps and source IPs for anomaly detection
- Consider implementing account lockout after multiple failed attempts
- Use database least privilege principles - the application database user should have minimal permissions
For applications requiring Basic Auth, consider implementing additional security layers such as IP whitelisting, VPN requirements, or moving to more secure authentication mechanisms like OAuth2 or JWT tokens with refresh mechanisms.
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 |