Clickjacking in Adonisjs with Api Keys
Clickjacking in Adonisjs with Api Keys — how this specific combination creates or exposes the vulnerability
Clickjacking is a client-side attack where an attacker tricks a user into clicking UI elements that are invisible or disguised. In AdonisJS applications that expose authenticated endpoints via API keys, clickjacking can be combined with weak authentication boundaries to escalate risk. When API keys are used for authorization but the frontend relies on standard cookie-based sessions or embeds sensitive actions inside iframes, an attacker can overlay invisible controls or mask legitimate UI elements to invoke privileged operations without user intent.
AdonisJS does not provide built-in clickjacking protections for API routes out of the box. If your application serves authenticated API responses to browsers and embeds those APIs inside third-party frames (e.g., embedding a settings form inside an iframe), an attacker can set up a transparent layer that captures clicks. API keys alone do not prevent clickjacking because they authenticate the request, but they do not enforce a same-origin policy or frame-busting behavior in the client. Attackers can craft pages that load your AdonisJS UI or API console inside an invisible iframe and trigger state-changing requests (e.g., changing email or rotating API keys) via user interaction.
The combination of API keys and iframe-based UI significantly expands the attack surface. For example, an admin page that rotates API keys might be embedded in an external site via iframe; an attacker’s page could overlay a button that appears to perform a benign action but actually triggers the key rotation endpoint. Because the request includes a valid API key (often stored in localStorage or cookies), AdonisJS processes it as legitimate. MiddleBrick’s scans detect such risky UI embedding patterns and flag them under unsafe consumption and input validation checks.
Unauthenticated LLM endpoint detection does not directly mitigate clickjacking, but it highlights the importance of securing all exposed interfaces. If an attacker can trick a user into invoking an LLM endpoint via a clickjacked UI, the request may execute with the victim’s API key context. This underscores the need to couple API key usage with anti-CSRF tokens or strict CORS and frame-ancestors policies in AdonisJS.
Api Keys-Specific Remediation in Adonisjs — concrete code fixes
Remediation focuses on ensuring API key usage does not inadvertently enable clickjacking vectors. You should enforce strict origin checks and avoid embedding authenticated UI inside iframes. Below are concrete AdonisJS patterns to reduce risk.
Set frame-ancestors CSP header
Prevent your authenticated pages from being embedded by setting a Content-Security-Policy header with frame-ancestors. In AdonisJS, add middleware to set this on responses for routes that render UI or expose API key operations.
// start/middleware/csp.js
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class CspMiddleware {
public async handle({ response, next }: HttpContextContract) {
response.header('Content-Security-Policy', "frame-ancestors 'self' https://trusted.yourdomain.com")
await next()
}
}
Rotate API keys with anti-CSRF safeguards
When implementing API key rotation, require a CSRF token or a custom header in addition to the API key. Do not rely on API keys alone for state-changing operations in browser contexts.
// routes.ts
import Route from '@ioc:Adonis/Core/Route'
Route.post('/api/keys/rotate', async ({ request, response }: HttpContextContract) => {
const providedCsrf = request.header('x-csrf-token')
const sessionCsrf = request.session().get('csrfToken')
if (!sessionCsrf || providedCsrf !== sessionCsrf) {
return response.badRequest({ error: 'Invalid CSRF token' })
}
const newKey = generateSecureKey()
await User.query().where('id', request.user!.id).update({ apiKey: hashKey(newKey) })
return response.ok({ key: newKey })
})
Serve API key endpoints with restrictive CORS
Ensure that endpoints managing API keys only accept requests from known origins. This prevents malicious sites from making authenticated requests even if a user is logged in.
// start/middleware/cors-keys.js
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class CorsKeysMiddleware {
public async handle({ response, next }: HttpContextContract) {
response.header('Access-Control-Allow-Origin', 'https://your-trusted-app.com')
response.header('Access-Control-Allow-Credentials', 'true')
response.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE')
response.header('Access-Control-Allow-Headers', 'Authorization,Content-Type,x-csrf-token')
await next()
}
}
Avoid embedding authenticated UI in third-party frames
If you must display sensitive configuration, host it on your own domain with the CSP header above. Do not allow arbitrary sites to embed your authenticated AdonisJS dashboard or API key management console.