Broken Authentication in Hapi with Cockroachdb
Broken Authentication in Hapi with Cockroachdb — how this specific combination creates or exposes the vulnerability
Broken Authentication in a Hapi application using CockroachDB typically arises from a mismatch between session or token handling logic and how user records are stored and validated in the database. Hapi does not enforce authentication by default; it relies on developers to implement strategies using plugins like hapi-auth-jwt2 or session-based approaches. When these strategies interact with CockroachDB, several implementation-level weaknesses can expose authentication bypass or credential leakage risks.
One common pattern is constructing SQL queries by string concatenation instead of using parameterized statements. For example, a developer might write:
const username = request.payload.username;
const query = 'SELECT * FROM users WHERE username = \' + username + \'';
const result = await pool.query(query);
This opens the door to SQL injection, allowing an attacker to manipulate the query and potentially authenticate as any user without a valid password. CockroachDB, while PostgreSQL-wire compatible, does not prevent such injection if the client driver receives malformed queries. Additionally, storing passwords as plain text or using weak hashing (e.g., unsalted SHA-1) in user records means that if CockroachDB is compromised, attackers can recover credentials easily.
Another vulnerability specific to this stack is insecure session storage. If session identifiers are stored in cookies without the Secure and HttpOnly flags, or if session data is kept in CockroachDB without encryption at rest, an attacker who intercepts a session ID can hijack authenticated sessions. Hapi’s cookie-based session handling must explicitly set these flags and tie sessions to user metadata stored securely in CockroachDB.
JWT-based setups can also be misconfigured. If the secret or private key used to sign tokens is hardcoded or derived from weak sources, an attacker can forge tokens and authenticate as any user. Since CockroachDB may store public keys or token metadata, improper access controls on that table can further expose the system. These issues align with findings from the Authentication and BOLA/IDOR checks in middleBrick scans, which detect weak authentication flows and insecure direct object references in API endpoints.
Cockroachdb-Specific Remediation in Hapi — concrete code fixes
To remediate Broken Authentication in Hapi with CockroachDB, adopt parameterized queries, strong password hashing, and secure session/JWT management. Below are concrete, working code examples.
1. Parameterized Queries with @cockroachdb/pq
Always use placeholders to prevent SQL injection. The official CockroachDB Node.js driver supports parameterized statements.
const Hapi = require('@hapi/hapi');
const { Pool } = require('@cockroachdb/pq');
const bcrypt = require('bcrypt');
const pool = new Pool({
connectionString: 'postgresql://user:password@localhost:26257/dbname?sslmode=require',
});
const init = async () => {
const server = Hapi.server({ port: 3000, host: 'localhost' });
server.route({
method: 'POST',
path: '/login',
handler: async (request, h) => {
const { username, password } = request.payload;
try {
const { rows } = await pool.query(
'SELECT id, password_hash FROM users WHERE username = $1',
[username]
);
if (rows.length === 0) {
return { error: 'Invalid credentials' };
}
const user = rows[0];
const isValid = await bcrypt.compare(password, user.password_hash);
if (!isValid) {
return { error: 'Invalid credentials' };
}
// Create secure session or JWT here
return { success: true, userId: user.id };
} catch (err) {
server.log(['error', 'auth'], err);
return { error: 'Internal server error' };
}
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
init().catch(err => {
console.error(err);
process.exit(1);
});
2. Secure Password Storage with bcrypt
Store passwords using bcrypt with a work factor of 10–12. Never store plain text or weakly hashed passwords.
const saltRounds = 12;
const hashedPassword = await bcrypt.hash(password, saltRounds);
// Store hashedPassword in CockroachDB
3. Secure Cookie Settings for Session-Based Auth
When using Hapi’s cookie authentication, enforce Secure, HttpOnly, and SameSite attributes.
server.state('sessionId', {
ttl: 24 * 60 * 60 * 1000,
isSecure: true,
isHttpOnly: true,
encoding: 'base64json',
path: '/',
sameSite: 'strict'
});
4. JWT Best Practices
If using JWT, keep secrets in environment variables and set short expiration times.
const JWT_SECRET = process.env.JWT_SECRET;
// When signing
const token = jwt.sign({ userId: user.id }, JWT_SECRET, { expiresIn: '15m' });
// Verify with strict algorithms
jwt.verify(token, JWT_SECRET, { algorithms: ['HS256'] });
These steps reduce the risk of Broken Authentication and align with findings that middleBrick may flag under Authentication, BOLA/IDOR, and Unsafe Consumption checks. The goal is to ensure that identity verification and session handling remain robust end-to-end.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |