Dns Rebinding in Adonisjs with Firestore
Dns Rebinding in Adonisjs with Firestore — how this specific combination creates or exposes the vulnerability
Dns rebinding occurs when an attacker forces a victim’s browser to resolve a domain to an internal IP, bypassing same-origin policies. In Adonisjs applications that interact with Google Cloud Firestore, this can expose internal Firestore endpoints to a remote attacker if the client-side code or server-side route handling relies on host-based trust rather than strict authentication and origin validation.
Consider an Adonisjs server that proxies Firestore operations through API routes. If the route uses the Firestore client initialized with a project ID but does not enforce strict CORS, validate the request origin, or use service account credentials securely on the server, a malicious site can make the browser issue requests to the Adonisjs route. The route, in turn, may call Firestore using elevated service account permissions, allowing the attacker to indirectly perform Firestore actions through the victim’s authenticated session.
For example, an attacker might craft a page that opens a WebSocket or long-polling connection to the Adonisjs endpoint, causing the browser to rebind the domain to 127.0.0.1 or another internal address. If the Adonisjs route does not validate the host or IP and passes unchecked parameters into Firestore calls (e.g., document paths), this can lead to unauthorized data access or manipulation. The Firestore SDK does not inherently prevent such misuse; it trusts the credentials provided. Therefore, the vulnerability lies in how Adonisjs integrates with Firestore — missing origin checks, overly permissive CORS, or insecure use of service account keys — not in Firestore itself.
Real-world impact can include reading or modifying Firestore documents, escalating privileges via modified queries, or exfiltrating sensitive data. This maps to common weaknesses in input validation and authorization (OWASP API Top 10:2023 Broken Object Level Authorization) and can be detected by middleBrick’s BOLA/IDOR and Input Validation checks, which test whether endpoints properly verify resources and user permissions.
Firestore-Specific Remediation in Adonisjs — concrete code fixes
To mitigate Dns rebinding risks when using Firestore in Adonisjs, apply defense-in-depth: strict CORS, origin validation, parameterized queries, and secure credential handling. Below are concrete steps and code examples.
1. Configure CORS and validate origins
Ensure your Adonisjs API routes only accept requests from trusted origins. Use Adonisjs CORS configuration and explicitly check the Origin header in critical routes.
// start/handle.ts
import { cors } from '@ioc:Adonis/Addons/Cors'
export const corsConfig = cors({
enabled: true,
origin: ['https://your-trusted-app.com'],
allowHeaders: ['Content-Type', 'Authorization'],
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
})
// In a route handler, additionally validate the host
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export async function validateOrigin(ctx: HttpContextContract) {
const allowedHosts = ['your-trusted-app.com', 'api.your-trusted-app.com']
const host = ctx.request.header('host') || ''
const origin = ctx.request.header('origin') || ''
if (!allowedHosts.includes(host) || !origin.includes('your-trusted-app.com')) {
ctx.response.badRequest({ error: 'Invalid origin' })
}
}
2. Use Firestore with service account securely on the server only
Never expose service account keys to the client. Initialize Firestore server-side and use parameterized queries to avoid injection via document paths or collection names.
// services/firestore.ts
import { Firestore, doc, getDoc, updateDoc } from 'firebase-admin/firestore'
import { initializeApp } from 'firebase-admin/app'
initializeApp({
credential: initializeApp.credential.cert({
projectId: process.env.GCP_PROJECT_ID,
clientEmail: process.env.GCP_CLIENT_EMAIL,
privateKey: process.env.GCP_PRIVATE_KEY?.replace(/\\n/g, '\n'),
}),
})
export const db = Firestore()
// Example: get document by validated ID
export async function getUserDoc(userId: string) {
// Validate userId to prevent path traversal
if (!/^[a-zA-Z0-9_-]{1,100}$/.test(userId)) {
throw new Error('Invalid user ID')
}
const userRef = doc(db, 'users', userId)
const snap = await getDoc(userRef)
return snap.exists() ? snap.data() : null
}
3. Parameterize queries and avoid dynamic collection names
Do not concatenate user input into Firestore paths. Use strict allowlists for collections and document IDs.
// controllers/users_controller.ts
import { db } from 'App/Services/firestore'
import { doc, getDoc } from 'firebase-admin/firestore'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export class UsersController {
public async show({ params, response }: HttpContextContract) {
const { userId } = params
// Strict validation
if (!/^[a-zA-Z0-9_-]+$/.test(userId)) {
return response.badRequest({ error: 'Invalid user ID' })
}
const userDoc = await getDoc(doc(db, 'users', userId))
return userDoc.exists() ? userDoc.data() : response.notFound()
}
}
4. Enforce authentication and authorization on every route
Even if CORS is locked, ensure each route verifies the session or token and applies per-user authorization (BOLA checks) before accessing Firestore.
// middleware/ensure_auth.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default async function ensureAuth(ctx: HttpContextContract) {
if (!ctx.auth.user) {
ctx.response.unauthorized({ error: 'Unauthenticated' })
}
// Optionally attach tenant or user scope for Firestore queries
ctx.firestoreUserScope = `users/${ctx.auth.user.id}`
}
5. Monitor and test with middleBrick
Use middleBrick’s CLI to scan your endpoints for Dns rebinding indicators, such as missing origin validation or insecure Firestore usage. Run middlebrick scan <url> to get a security risk score and prioritized findings, including BOLA/IDOR and Input Validation checks that map to these concerns.