HIGH sql injectionbasic auth

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 IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Why is SQL injection in Basic Auth particularly dangerous compared to form-based authentication?
Basic Auth transmits credentials in every request, making it susceptible to network sniffing if not using HTTPS. Additionally, Basic Auth implementations often have simpler code paths that might skip some security validations present in form-based systems. The Base64 encoding is easily decoded, and many Basic Auth implementations have legacy code that predates modern SQL injection prevention techniques.
Can middleBrick detect SQL injection in Basic Auth endpoints without credentials?
Yes, middleBrick performs black-box scanning that tests the unauthenticated attack surface. The scanner sends crafted Authorization headers with SQL injection payloads and analyzes responses for vulnerability indicators such as authentication bypass, error message leakage, or timing anomalies. No credentials or source code access are required.