HIGH clickjackingadonisjsdynamodb

Clickjacking in Adonisjs with Dynamodb

Clickjacking in Adonisjs with Dynamodb — how this specific combination creates or exposes the vulnerability

Clickjacking is a client-side UI redress attack in which an attacker tricks a user into clicking or interacting with a transparent or opaque element embedded over a legitimate page. When an AdonisJS application uses DynamoDB as its data store and renders views that include embedded resources or dynamic UI components, misconfigured HTTP headers and insecure frame handling can expose endpoints to clickjacking.

AdonisJS does not enforce a default X-Frame-Options header for all responses. If routes rendering forms or dashboards—such as a DynamoDB-backed user settings page—do not explicitly set frame-prevention headers, browsers may render the page inside an <iframe> on a malicious site. Attackers can overlay invisible controls or CSS on top of the embedded content, causing unintended actions like updating a DynamoDB record via a crafted POST request initiated without the user’s knowledge.

DynamoDB itself does not introduce clickjacking, but the application logic that reads and writes to DynamoDB can be invoked through these forged interactions. For example, an authenticated request that calls a controller method to update user preferences in DynamoDB could be triggered by a hidden form submission from an embedded frame. If the endpoint relies solely on session cookies for authentication and lacks CSRF tokens or SameSite cookie attributes, the request is executable even when embedded. The risk is compounded when the UI includes inline JavaScript that dynamically constructs forms or modifies headers, which can be manipulated through CSS or script injection within the frame to alter the intended request parameters.

Moreover, if AdonisJS views include external widgets or iframes—such as analytics or third-party login buttons—that originate from untrusted sources, they can serve as vectors for embedding the application’s own pages. Developers might inadvertently expose administrative or data-modifying pages that interact with DynamoDB without considering frame context. The absence of Content Security Policy (CSP) frame-ancestors directives further allows arbitrary origins to embed the page, enabling attackers to design convincing phishing interfaces that overlay the legitimate application UI.

In a typical AdonisJS + DynamoDB stack, the following conditions create a exploitable clickjacking surface:

  • Controllers returning HTML views that perform state changes (e.g., updating DynamoDB records) without anti-CSRF tokens.
  • Missing or permissive X-Frame-Options or Content-Security-Policy frame-ancestors headers.
  • Use of cookies for authentication without SameSite=Strict or Lax attributes.
  • Dynamic rendering of forms or links that directly invoke DynamoDB write operations based on GET requests or poorly validated POST inputs.

Dynamodb-Specific Remediation in Adonisjs — concrete code fixes

Remediation focuses on server-side header enforcement, CSRF protection, and secure cookie settings within the AdonisJS application layer. DynamoDB operations remain unchanged, but the surrounding HTTP interface must prevent unauthorized embedding and interaction.

1. Enforce Frame-Defpendency Headers

Ensure every response that renders UI or performs state changes includes X-Frame-Options or Content-Security-Policy headers. In AdonisJS, you can use middleware to apply these headers globally or per route.

// start/kernel.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class Kernel {
  public async handle(ctx: HttpContextContract, next: () => Promise) {
    // Apply globally, or skip for public APIs
    ctx.response.headers.set('X-Frame-Options', 'DENY')
    ctx.response.headers.set(
      'Content-Security-Policy',
      "frame-ancestors 'self'; frame-src 'none'"
    )
    await next()
  }
}

For routes that must be embeddable (e.g., public dashboards), use a more restrictive policy instead of DENY:

ctx.response.headers.set('Content-Security-Policy', "frame-ancestors 'self' https://trusted.partner.com")

2. Secure Cookies for Authentication

Ensure session cookies used for DynamoDB-authenticated requests include SameSite and Secure attributes. In AdonisJS, configure this in start/session.ts.

import { SessionConfig } from '@ioc:Adonis/Addons/Session'

const sessionConfig: SessionConfig = {
  driver: 'cookie',
  cookie: {
    name: 'app_session',
    httpOnly: true,
    secure: true, // send only over HTTPS
    sameSite: 'strict', // or 'lax' for limited cross-site GETs
    path: '/',
  },
}
export default sessionConfig

3. CSRF Protection for State-Changing Requests

AdonisJS includes built-in CSRF protection for form submissions. Ensure it is enabled for routes that modify DynamoDB data. Validate origins and use anti-CSRF tokens in forms.

// In a controller method handling DynamoDB updates
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { schema, rules } from '@ioc:Adonis/Core/Validator')
import DynamoDB from '@aws-sdk/client-dynamodb'

export default class ProfileController {
  public async updateProfile({ request, auth, response }: HttpContextContract) {
    const bodySchema = schema.create({
      userId: schema.string({ trim: true }),
      theme: schema.string.optional(),
    })
    const validatedData = await request.validate({ schema: bodySchema })

    // Ensure the authenticated user matches the request payload
    const user = auth.user
    if (user?.id !== validatedData.userId) {
      return response.badRequest({ error: 'Unauthorized' })
    }

    const client = new DynamoDB({ region: 'us-east-1' })
    const params = {
      TableName: 'UserSettings',
      Key: { userId: { S: validatedData.userId } },
      UpdateExpression: 'SET theme = :theme',
      ExpressionAttributeValues: {
        ':theme': { S: validatedData.theme },
      },
    }
    await client.send(new DynamoDB.UpdateCommand(params))

    return response.ok({ status: 'updated' })
  }
}

This example shows a secure update flow: validated input, ownership check, and DynamoDB interaction. The accompanying CSRF token (handled automatically by AdonisJS for cookie-based sessions) prevents cross-origin forged requests.

4. Avoid Unsafe GET-Based Writes

Ensure DynamoDB mutations are performed via POST, PUT, or DELETE methods, not GET. AdonisJS route definitions should reflect this.

// routes.ts
Route.put('/profile/:userId', 'ProfileController.updateProfile')
     .as('profile.update')
// Avoid:
// Route.get('/profile/:userId/update-theme', 'ProfileController.updateTheme')

5. Middleware to Detect and Block Embedding

Add lightweight logic to critical routes to reject requests that include an Referer or Origin header indicating an external site, if your application does not expect cross-origin interactions.

export default class AntiClickjackingMiddleware {
  public async handle(ctx: HttpContextContract, next: () => Promise) {
    const allowedOrigin = 'https://yourdomain.com'
    const origin = ctx.request.header('origin')
    const referer = ctx.request.header('referer')
    if (origin && !origin.startsWith(allowedOrigin)) {
      return ctx.response.unauthorized({ error: 'Invalid origin' })
    }
    if (referer && !referer.startsWith(allowedOrigin)) {
      return ctx.response.unauthorized({ error: 'Invalid referer' })
    }
    await next()
  }
}

Frequently Asked Questions

Can DynamoDB's conditional writes prevent clickjacking-related data corruption?
No. Conditional writes in DynamoDB (e.g., using ConditionExpression) enforce data consistency at the database level but do not prevent clickjacking. Clickjacking is a UI redress issue; the attack occurs before the request reaches DynamoDB. Protection must be implemented at the HTTP layer via headers, CSRF tokens, and SameSite cookies.
Does middleBrick detect clickjacking risks in AdonisJS applications using DynamoDB?
Yes. middleBrick scans unauthenticated attack surfaces and includes checks for missing frame-protection headers and insecure cookie attributes. The dashboard provides a security risk score (A–F), per-category breakdowns, and prioritized findings with remediation guidance to help identify clickjacking and other UI-related vulnerabilities.