HIGH dns rebindingadonisjscockroachdb

Dns Rebinding in Adonisjs with Cockroachdb

Dns Rebinding in Adonisjs with Cockroachdb — how this specific combination creates or exposes the vulnerability

DNS rebinding is an attack that manipulates DNS responses to make a victim browser believe a remote host is reachable at an internal IP address. When an AdonisJS application uses CockroachDB and relies on hostname-based resolution without additional safeguards, the framework’s HTTP server and database client interactions can expose an expanded attack surface.

In AdonisJS, services such as the database layer are configured centrally (typically in config/database.ts). If the configuration specifies a CockroachDB hostname that resolves to a public address at startup but can be altered via DNS to an internal resource, an attacker may leverage a malicious domain that initially resolves to a controlled external IP and later switches to a private IP such as 127.0.0.1 or a CockroachDB node inside a private network. Because AdonisJS does not inherently validate that the resolved database endpoint remains consistent with the intended network zone, the application may unwittingly route queries to an unintended host after the rebinding occurs.

Consider an AdonisJS application that connects to CockroachDB using a hostname like cockroachdb.example.com. An attacker registers cockroachdb.example.com, controls the DNS records, and sets a very low TTL. The initial resolution points to an attacker-controlled server that responds with a valid TLS certificate for the domain to avoid certificate errors. After the victim’s browser establishes a connection, the attacker switches the DNS record to point to an internal service, such as a CockroachDB node or an internal metadata service. If the AdonisJS application reuses the same long-lived connection or does not enforce strict hostname verification, it may accept the redirected endpoint and interact with the internal service using the application’s database permissions.

The risk is compounded when the application exposes endpoints that perform database actions based on user input without adequate validation. For example, an endpoint that accepts a cluster name or node identifier and uses it to construct a connection string or to select a CockroachDB tenant may inadvertently allow an attacker to pivot from a public-facing service to internal administrative interfaces. Because CockroachDB supports multi-tenancy and SQL user permissions, an attacker who successfully redirects traffic might execute statements under the context of the application’s service account, potentially reading or modifying data that should remain isolated.

AdonisJS mitigations should focus on ensuring that network boundaries are explicit and that the application does not implicitly trust DNS after initial resolution. This includes avoiding dynamic hostname assembly from user input, enforcing strict certificate validation, and ensuring that CockroachDB connections are established only to pre-approved hosts. Security checks such as those provided by middleBrick that test for SSRF and input validation are particularly useful in identifying whether an application is vulnerable to DNS manipulation in this context.

Cockroachdb-Specific Remediation in Adonisjs — concrete code fixes

To reduce DNS rebinding risk when using CockroachDB with AdonisJS, prefer static IP connections, enforce certificate pinning, and avoid constructing connection parameters from untrusted data. The following patterns demonstrate secure configurations and request handling.

1. Database configuration using static IPs and TLS

Configure config/database.ts to use explicit IP addresses or hostnames that are not user-controlled, and enable strict TLS verification.

import { defineConfig } from '@ioc:Adonis/Lucid/Orm'

export default defineConfig({
  connection: 'cockroachdb',
  connections: {
    cockroachdb: {
      client: 'postgres',
      host: '10.4.3.12', // static IP or internal hostname not exposed to public DNS
      port: 26257,
      user: 'app_user',
      password: 'StrongPassword123!',
      database: 'app_db',
      ssl: {
        rejectUnauthorized: true,
        ca: fs.readFileSync(path.resolve(__dirname, 'certs/ca.pem')).toString(),
        key: fs.readFileSync(path.resolve(__dirname, 'certs/client.key')).toString(),
        cert: fs.readFileSync(path.resolve(__dirname, 'certs/client.pem')).toString(),
      },
    },
  },
})

2. Validating and sanitizing user input before query building

Ensure that any user-supplied values used in database operations are validated against a strict allowlist. For example, if an endpoint accepts an organization slug to select a CockroachDB tenant, validate the slug format and map it to a pre-defined tenant ID rather than interpolating it into connection strings.

import { schema } from '@ioc:Adonis/Core/Validator'

const organizationSchema = schema.create({
  orgSlug: schema.string({}, [
    (value) => ['tenant-a', 'tenant-b', 'tenant-c'].includes(value),
  ]),
})

export async function getTenantConfig(ctx: HttpContextContract) {
  const payload = await ctx.validate({ schema: organizationSchema })
  const tenantConfig = tenantsConfig[payload.orgSlug] // predefined mapping
  const rows = await Database.from('org_metadata')
    .where('org_slug', tenantConfig.id)
    .select('connection_string')
  // Use rows[0].connection_string for a trusted CockroachDB connection string
}

3. Using environment-based configuration with no user-controlled hostnames

Load CockroachDB connection details from environment variables that are set at deployment time and never derived from request parameters. This prevents an attacker from influencing the target host through application configuration endpoints.

// In .env
COCKROACH_HOST=10.4.3.12
COCKROACH_PORT=26257
COCKROACH_USER=app_user
COCKROACH_PASSWORD=StrongPassword123!
COCKROACH_DB=app_db

// In config/database.ts
const host = Env.get('COCKROACH_HOST')
const port = Env.get('COCKROACH_PORT', '26257')

export default defineConfig({
  connection: 'cockroachdb',
  connections: {
    cockroachdb: {
      client: 'postgres',
      host,
      port: Number(port),
      user: Env.get('COCKROACH_USER'),
      password: Env.get('COCKROACH_PASSWORD'),
      database: Env.get('COCKROACH_DB'),
      ssl: {
        rejectUnauthorized: true,
        // certificate handling as above
      },
    },
  },
})

4. Enforcing network segmentation and access controls

Ensure that CockroachDB nodes are not reachable from public internet and that firewall rules restrict source IPs to known AdonisJS application servers. Within the application, avoid features that allow arbitrary host specification after initial configuration, such as dynamic connection switching based on request headers or query parameters.

Frequently Asked Questions

Can middleBrick detect DNS rebinding risks in an AdonisJS app using CockroachDB?
Yes, middleBrick tests for input validation and SSRF. Its scans check whether an API endpoint can be tricked into interacting with internal network endpoints, which helps identify weaknesses that could be exploited via DNS rebinding.
Does enabling mTLS in AdonisJS fully prevent DNS rebinding with CockroachDB?
Mutual TLS adds strong authentication between client and server, but DNS rebinding primarily exploits trust in network location after resolution. You must also use static IPs, avoid dynamic host selection, and validate input to prevent an attacker from redirecting traffic to unintended internal services.