MEDIUM clickjackingadonisjs

Clickjacking in Adonisjs

How Clickjacking Manifests in Adonisjs

Clickjacking in Adonisjs applications typically exploits the framework's view rendering system and HTTP response handling. The vulnerability arises when an Adonisjs application fails to implement proper X-Frame-Options headers or Content Security Policy (CSP) directives, allowing malicious websites to embed your application's pages within iframes.

In Adonisjs, this often occurs in controller actions that render sensitive pages without frame protection. For example, an admin dashboard route like:

Route.get('/admin/dashboard', 'AdminController.dashboard')

If the dashboard view contains forms for critical operations (user management, payment processing, data export), an attacker can create a malicious page that loads this dashboard in an invisible iframe. The attacker then tricks users into clicking on seemingly innocuous buttons that actually trigger actions in the hidden iframe.

Adonisjs's view engine (Edge) can inadvertently contribute to clickjacking risks when developers use partial views for sensitive components without considering frame protection. A common pattern is embedding authentication forms or confirmation dialogs as reusable components:

@component('components.auth-modal') @endcomponent

Without proper headers, these components become vulnerable when rendered in contexts where they shouldn't be directly accessible.

The framework's middleware system provides opportunities for clickjacking protection, but developers often overlook adding frame-busting headers. Adonisjs's built-in middleware doesn't include clickjacking protection by default, requiring explicit implementation in either global middleware or specific route groups.

Adonisjs-Specific Detection

Detecting clickjacking vulnerabilities in Adonisjs applications requires examining both the HTTP response headers and the application's routing structure. middleBrick's black-box scanning approach is particularly effective here, as it tests the actual runtime behavior without requiring source code access.

When middleBrick scans an Adonisjs endpoint, it specifically checks for:

  • Missing X-Frame-Options header (DENY or SAMEORIGIN values)
  • Missing Content-Security-Policy frame-ancestors directive
  • Missing frame-busting JavaScript patterns
  • Exposed sensitive endpoints that should never be framed

For Adonisjs applications, middleBrick's OpenAPI analysis is especially valuable. It examines your API specifications to identify endpoints that handle sensitive operations, then cross-references these with actual HTTP responses to verify frame protection is in place.

Developers can also perform manual detection using curl or browser developer tools:

curl -I https://yourapp.com/admin/dashboard

Look for X-Frame-Options and Content-Security-Policy headers. In Adonisjs, you can create a diagnostic middleware to log frame-related headers:

class FrameSecurityMiddleware { 
 async handle({ response }, next) { 
 await next() 
 console.log('X-Frame-Options:', response.headers['x-frame-options']) 
 console.log('Content-Security-Policy:', response.headers['content-security-policy']) 
 }}

Adonisjs-Specific Remediation

Adonisjs provides several native approaches to prevent clickjacking. The most straightforward is implementing a middleware that sets appropriate headers. Here's an Adonisjs-specific implementation:

class FrameSecurityMiddleware { 
 async handle({ response }, next) { 
 response.header('X-Frame-Options', 'DENY') 
 response.header('Content-Security-Policy', "frame-ancestors 'none'") 
 await next() 
 } 
}

Register this middleware globally in start/kernel.ts or apply it selectively to sensitive route groups:

Route.group(() => { 
 Route.get('/admin/dashboard', 'AdminController.dashboard') 
 Route.post('/admin/users', 'AdminController.createUser') 
}).middleware(['frame-security'])

For applications requiring more granular control, Adonisjs's middleware can inspect the request context:

class FrameSecurityMiddleware { 
 async handle({ response, request }, next) { 
 const isSensitiveRoute = request.url().includes('/admin') 
 if (isSensitiveRoute) { 
 response.header('X-Frame-Options', 'DENY') 
 response.header('Content-Security-Policy', "frame-ancestors 'none'") 
 } 
 await next() 
 } 
}

Adonisjs's view system also allows frame-busting JavaScript as a fallback. Include this in your main layout or specific sensitive views:

@if(Config.get('app.env') === 'production') 
<script> 
 if (top.location != location) { 
 top.location.href = location.href 
 } 
</script> 
@endif

For comprehensive protection, combine header-based and JavaScript-based approaches. Adonisjs's middleware system makes this straightforward:

class FrameSecurityMiddleware { 
 async handle({ response }, next) { 
 response.header('X-Frame-Options', 'DENY') 
 response.header('Content-Security-Policy', "frame-ancestors 'none'") 
 response.implicitEnd = false 
 await next() 
 
 // Add frame-busting script if headers might be stripped 
 response.send(response.response.toString() + '
<script>if(top!=self)top.location=self.location;</script>') 
 } 
}

Frequently Asked Questions

Does Adonisjs provide built-in clickjacking protection?
No, Adonisjs does not include built-in clickjacking protection. Developers must explicitly implement X-Frame-Options headers, Content-Security-Policy directives, or frame-busting JavaScript. This is typically done through custom middleware that sets the appropriate response headers.
How does middleBrick detect clickjacking in Adonisjs applications?
middleBrick performs black-box scanning that tests actual HTTP responses from your Adonisjs endpoints. It specifically checks for missing X-Frame-Options headers, absent Content-Security-Policy frame-ancestors directives, and evaluates whether sensitive endpoints are exposed to framing. The scanner works without requiring access to your source code or configuration.