Rainbow Table Attack in Adonisjs with Basic Auth
Rainbow Table Attack in Adonisjs with Basic Auth — how this specific combination creates or exposes the vulnerability
A rainbow table attack in AdonisJS when using Basic Auth centers on how passwords are stored and compared. Basic Auth transmits credentials as base64-encoded username:password on each request. If the server stores passwords as unsalted or poorly hashed values, an attacker who gains access to the database or intercepts traffic can use precomputed tables to reverse common passwords. In AdonisJS, the default hasher may be configured to use fast algorithms (e.g., SHA256) without per-user salts. Without salts, identical passwords produce identical hashes, making them vulnerable to rainbow table lookups. An attacker can generate tables for common passwords and match hashes from the user table. If the application serves an unauthenticated endpoint that leaks password hashes (e.g., via verbose error messages or information disclosure), the attacker can map hashes back to plaintext using the table. AdonisJS’s session or token handling may also expose timing differences when comparing hashes, aiding offline cracking. The combination of predictable storage and unauthenticated access to endpoints that handle Basic Auth credentials amplifies risk, especially if the transport lacks encryption or the server misconfigures protections against enumeration.
Basic Auth-Specific Remediation in Adonisjs — concrete code fixes
Remediation requires two changes: strong password hashing with salts and secure transport. Use AdonisJS’s built-in hashing utilities with a modern algorithm and per-user random salts. Never store or compare raw passwords. When verifying credentials, hash the provided password with the same salt and compare the resulting hash in constant time to prevent timing attacks. Enforce HTTPS to protect credentials in transit, as base64 encoding in Basic Auth is not encryption. Below are concrete code examples for secure Basic Auth in AdonisJS.
Secure user registration and password hashing
import { Hash } from '@ioc:Adonis/Core/Hash'
export async function registerUser(username: string, password: string) {
// Hash with a strong, adaptive algorithm (bcrypt by default in AdonisJS)
const hashedPassword = await Hash.make(password)
await User.create({
username,
password_hash: hashedPassword,
// AdonisJS automatically handles per-user salts when using Hash.make
})
}
Secure Basic Auth verification in a controller
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { Hash } from '@ioc:Adonis/Core/Hash'
import User from 'App/Models/User'
export default class AuthController {
public async basicAuth({ request, auth, response }: HttpContextContract) {
const { username, password } = request.basicAuth()
if (!username || !password) {
return response.unauthorized({ message: 'Missing credentials' })
}
const user = await User.findBy('username', username)
if (!user) {
// Use a generic message and a constant-time comparison to avoid user enumeration
await Hash.verify(password, '$2a$10$dummyforsafetyanduniformtimingdummyforsafetyanduniformtimingdummy')
return response.unauthorized({ message: 'Invalid credentials' })
}
const passwordMatches = await Hash.verify(password, user.password_hash)
if (!passwordMatches) {
return response.unauthorized({ message: 'Invalid credentials' })
}
// Issue a session or token as appropriate for your application
const token = await auth.use('api').generate(user)
return response.ok({ token })
}
}
Enforce HTTPS and security headers
Ensure your AdonisJS server terminates TLS and sets headers to prevent downgrade attacks. Do not allow HTTP for authentication endpoints.
Additional hardening
- Rate-limit authentication endpoints to slow brute-force and rainbow table attempts.
- Avoid exposing password hashes in logs or error responses.
- Use a strong work factor for bcrypt (AdonisJS defaults are typically reasonable; verify your config).