Clickjacking in Restify
How Clickjacking Manifests in Restify
Clickjacking in Restify applications occurs when an attacker embeds your API or web interface within an invisible iframe, tricking users into interacting with your application without their knowledge. Restify, being a Node.js framework for building REST APIs, can be vulnerable to clickjacking through several specific attack vectors.
The most common manifestation in Restify is when your application lacks proper X-Frame-Options headers or Content-Security-Policy directives. An attacker can create a malicious page that loads your Restify application's UI components (if any exist) or API endpoints that trigger state-changing operations within an iframe. When users visit the attacker's page, they might unknowingly click buttons or links that perform actions in your application.
Restify applications that serve both API endpoints and web-based admin interfaces are particularly susceptible. For example, if your Restify server includes endpoints for user management, account deletion, or financial transactions, an attacker could craft a page that makes these endpoints appear as legitimate UI elements. The user believes they're interacting with the attacker's content, but their clicks are actually triggering operations in your Restify application.
A specific Restify vulnerability pattern involves endpoints that accept POST requests without proper CSRF protection. An attacker could create a form that submits to your Restify endpoint, embed it in an iframe, and use CSS to make it invisible. When the user clicks anywhere on the malicious page, they're actually submitting the hidden form to your API, potentially creating data, transferring funds, or changing account settings.
Restify applications using middleware for authentication can also be exploited. If your authentication middleware doesn't properly validate the origin of requests or doesn't set appropriate security headers, an attacker can maintain a session within an iframe and perform actions on behalf of the authenticated user. This is particularly dangerous for endpoints that modify sensitive data or trigger financial operations.
Another Restify-specific scenario involves applications that serve single-page applications (SPAs) alongside their API. If the SPA doesn't implement proper security headers and is served from the same Restify server, the entire application becomes vulnerable to clickjacking attacks. The attacker can embed the SPA in an iframe and exploit any state-changing operations exposed through the UI.
Restify-Specific Detection
Detecting clickjacking vulnerabilities in Restify applications requires both manual code review and automated scanning. middleBrick's API security scanner specifically tests for clickjacking by attempting to load your Restify endpoints within iframes and checking for proper security headers.
To manually detect clickjacking in your Restify application, start by examining your server setup code. Look for the absence of X-Frame-Options headers and Content-Security-Policy directives. In Restify, this typically involves checking your server configuration where you set response headers. Here's what vulnerable code looks like:
const restify = require('restify');
const server = restify.createServer();
// Vulnerable: No security headers set
server.get('/api/users', (req, res) => {
res.send(users);
The scanner will test your endpoints by attempting to embed them in iframes and checking if they load successfully. It also examines your OpenAPI/Swagger specifications to identify endpoints that might be vulnerable to clickjacking-based attacks, particularly those that accept state-changing requests.
middleBrick specifically checks for these clickjacking indicators in Restify applications:
- Missing X-Frame-Options header (DENY or SAMEORIGIN)
- Missing Content-Security-Policy frame-ancestors directive
- Endpoints that accept POST/PUT/DELETE requests without proper CSRF protection
- Authentication endpoints that can be exploited through iframe-based session hijacking
- API endpoints that trigger financial transactions or data modifications
The scanner also tests for clickjacking through API endpoints that might be called via client-side JavaScript. Even if your API doesn't serve HTML, endpoints that can be triggered through AJAX calls from within an iframe can still be exploited for clickjacking attacks.
For Restify applications serving SPAs, middleBrick examines the integration between your API and frontend code. It checks whether your application properly separates API concerns from UI concerns and whether security headers are consistently applied across all served content.
Restify-Specific Remediation
Remediating clickjacking vulnerabilities in Restify requires implementing proper security headers and architectural changes. The most effective approach involves setting X-Frame-Options and Content-Security-Policy headers at the server level, then applying additional protections to sensitive endpoints.
Here's how to properly secure a Restify application against clickjacking:
const restify = require('restify');
const server = restify.createServer();
// Set security headers globally
server.pre((req, res, next) => {
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
res.setHeader('X-Content-Type-Options', 'nosniff');
next();
For applications that need to allow framing from specific origins, you can use a more granular approach:
const restify = require('restify');
const server = restify.createServer();
// Allow framing only from specific trusted origins
server.pre((req, res, next) => {
const allowedOrigins = ['https://yourtrusteddomain.com'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('X-Frame-Options', 'ALLOW-FROM ' + origin);
res.setHeader('Content-Security-Policy', `frame-ancestors ${origin}`);
} else {
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
}
next();
For sensitive API endpoints that perform state-changing operations, implement additional CSRF protection:
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
// Protect POST endpoints with CSRF
server.post('/api/users', csrfProtection, (req, res) => {
// Your endpoint logic here
res.send(200);
Another effective pattern is to separate your API server from any UI components. If your Restify application only serves API endpoints and doesn't serve HTML content, you can be more aggressive with security headers:
server.pre((req, res, next) => {
// Strict security for pure API servers
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
res.setHeader('Access-Control-Allow-Origin', 'https://yourapp.com');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
For applications that must serve both API and UI components, use route-specific middleware to apply different security policies:
// Apply strict security to API routes
server.use('/api/*', (req, res, next) => {
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
next();
Finally, implement proper authentication and session management. Ensure that session cookies have the HttpOnly and Secure flags set, and consider implementing same-site cookie policies:
server.use(restify.plugins.conditionalRequest());
server.use(restify.plugins.authorizationParser());
// Set secure cookie options
server.on('after', restify.plugins.auditLogger({
log: bunyan.createLogger({
name: 'audit-log'
})
By implementing these remediation strategies, you can effectively eliminate clickjacking vulnerabilities in your Restify applications and ensure that your API endpoints cannot be exploited through iframe-based attacks.