HIGH cross site request forgeryadonisjscockroachdb

Cross Site Request Forgery in Adonisjs with Cockroachdb

Cross Site Request Forgery in Adonisjs with Cockroachdb — how this specific combination creates or exposes the vulnerability

Cross Site Request Forgery (CSRF) in an AdonisJS application backed by CockroachDB arises when state-changing HTTP requests (POST, PUT, PATCH, DELETE) rely only on cookie-based session identifiers without a synchronizer token. Because CockroachDB is a distributed SQL database and AdonisJS typically uses session-based authentication (e.g., via @adonisjs/session), an attacker can craft a malicious site that triggers requests authenticated by the victim’s browser. Even though CockroachDB itself does not introduce CSRF, the way AdonisJS manages sessions and authenticates requests determines whether the application is vulnerable.

Consider an AdonisJS controller that updates a user’s email by deserializing a JSON body directly and writing to CockroachDB without verifying the request origin:

// resources/controllers/UserController.ts
import { schema } from '@ioc:Adonis/Core/Validator'
import User from 'App/Models/User'

export default class UsersController {
  public async updateEmail({ request, auth, response }) {
    const user = await auth.getUser()
    const body = request.only(['email'])
    // No CSRF protection here; relies solely on session cookie
    await user.merge({ email: body.email }).save()
    return response.ok({ updated: true })
  }
}

If this endpoint is exposed as a POST route and the application does not enforce anti-CSRF tokens (e.g., synchronizer token pattern), an attacker can host a page that submits a forged request to /users/update-email. Because CockroachDB does not enforce request origin checks, the database operation will proceed if the user’s authenticated session is valid. AdonisJS’s CSRF protection is primarily a middleware concern; omitting it or misconfiguring it leads to a broken synchronizer token flow across all backends, including CockroachDB.

Another scenario involves APIs that use cookie-based sessions rather than bearer tokens. If AdonisJS exposes endpoints that accept state-changing methods over cookies without CSRF tokens, and CockroachDB stores the authoritative data, the distributed nature of CockroachDB does not mitigate CSRF — the transaction will succeed on the correct tenant’s rows because the session is trusted. Therefore, the vulnerability is introduced by the framework’s configuration and the developer’s omission of CSRF checks, not by CockroachDB itself.

Cockroachdb-Specific Remediation in Adonisjs — concrete code fixes

Remediation focuses on ensuring AdonisJS validates the request origin for state-changing operations and that session handling is hardened. Use AdonisJS’s built-in CSRF middleware and synchronize tokens per request. The following example shows a secure controller update that reads a validated schema and writes to CockroachDB only after CSRF verification.

// resources/controllers/UserController.ts
import { schema } from '@ioc:Adonis/Core/Validator'
import User from 'App/Models/User'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class UsersController {
  public async updateEmail({ request, auth, response }: HttpContextContract) {
    const user = await auth.getUser()
    const bodySchema = schema.create({
      email: schema.string({ trim: true }, [rules.email()]),
    })
    const validatedBody = await request.validate({ schema: bodySchema })
    // CSRF token is verified by AdonisJS middleware before this runs
    await user.merge({ email: validatedBody.email }).save()
    return response.ok({ updated: true })
  }
}

Ensure the CSRF middleware is active in start/kernel.ts and that routes requiring protection are included:

// start/kernel.ts
import { HttpMiddlewareNames } from '@ioc:Adonis/Core/Application'

const middleware = {
  named: {
    csrf: () => import('#ioc/Middleware/Csrf'),
  },
}

export const http = {
  middleware: {
    enable: ['csrf'],
    global: true,
  },
}

For API tokens (e.g., JWT), CSRF is generally not required, but if cookies are used for authentication, synchronize a per-form token and validate it on the server. Below is a minimal route definition that enforces CSRF for a sensitive POST route to CockroachDB:

// start/routes.ts
import Route from '@ioc:Adonis/Core/Route'
import User from 'App/Models/User'

Route.post('/users/:id/email', async ({ params, request, response }) => {
  // CSRF middleware already validated the token
  const user = await User.findOrFail(params.id)
  const bodySchema = schema.create({
    email: schema.string({ trim: true }, [rules.email()]),
  })
  const { email } = await request.validate({ schema: bodySchema })
  await user.merge({ email }).save()
  return response.ok({ updated: true })
}).middleware(['csrf'])

Additionally, adopt secure cookie attributes and SameSite policies to reduce the attack surface. Configure sessions in config/session.ts to use SameSite=Strict or Lax and Secure in production, ensuring that cookies are not leaked to cross-origin contexts where CSRF could be more easily launched.

Frequently Asked Questions

Does using CockroachDB change how I should implement CSRF protection in AdonisJS?
No. CSRF protection is an application-layer concern in AdonisJS. CockroachDB is a database and does not enforce request origin policies. You must use AdonisJS CSRF middleware and synchronizer tokens regardless of the database.
Can AdonisJS’s built-in CSRF middleware protect all routes that write to CockroachDB?
Yes, if enabled globally or per-route. Ensure the CSRF middleware is active in start/kernel.ts and applied to state-changing routes. For public APIs using tokens, disable CSRF for those routes and rely on proper authentication instead.