HIGH clickjackingloopbackbearer tokens

Clickjacking in Loopback with Bearer Tokens

Clickjacking in Loopback with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Clickjacking is a client-side UI redress attack where an attacker tricks a user into interacting with a hidden or disguised element inside a transparent iframe. When a Loopback application relies solely on Bearer token authentication in an API context and does not enforce protections against embedding, a logged-in user’s authenticated requests can be hijacked. The combination is risky when an API response is consumed by a browser context (for example, a page that includes the API endpoint via an image or script tag) and the API trusts the presence of a Bearer token without additional anti-CSRF measures.

In a typical scenario, an attacker crafts a page that loads a sensitive Loopback API route inside an invisible iframe and overlays interactive controls (e.g., a transparent button) on top of it. If the user is authenticated via a Bearer token stored in browser storage or a cookie, the browser automatically includes the token in requests initiated by the iframe. Because the endpoint does not validate the request origin and treats the Bearer token as sufficient proof of intent, the malicious actions execute under the victim’s permissions. This becomes particularly dangerous for endpoints that perform state changes (POST/PUT/DELETE) or expose sensitive data, as the API may not differentiate between a legitimate user-initiated call and an embedded cross-origin call carrying the same Bearer token.

Even when Bearer tokens are transmitted in the Authorization header, an attacker can leverage CSS and HTML to mask the true destination of form actions or iframe content, making the UI appear benign. If the Loopback API does not include anti-CSRF tokens, referrer checks, or proper CORS and frame-ancestors policies, the presence of a Bearer token alone does not prevent clickjacking. The risk is compounded when the API serves responses that render in a browser (e.g., JSON used by client-side JavaScript that updates the DOM) because the token’s automatic inclusion can be abused to perform unauthorized operations on behalf of the authenticated user.

Bearer Tokens-Specific Remediation in Loopback — concrete code fixes

To mitigate clickjacking when using Bearer tokens in Loopback, combine secure token handling with anti-CSRF and framing controls. Below are concrete, realistic code examples that illustrate secure patterns.

1. Enforce strict CORS and prevent framing

Configure CORS to restrict origins and set frame-ancestors to prevent embedding. This reduces the ability of an attacker to load your API in an iframe regardless of token type.

const corsConfig = {
  origin: ['https://trusted.example.com'],
  methods: 'GET,POST',
  credentials: true
};
app.use(cors(corsConfig));

// Alternatively, set frame-ancestors via CSP header
app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy', "frame-ancestors 'self' https://trusted.example.com");
  next();
});

2. Use CSRF tokens for state-changing operations even with Bearer tokens

When your frontend is browser-based, pair Bearer tokens (for API authentication) with CSRF tokens (for request validation). Below is a simplified example using a cookie-based CSRF token and a custom Loopback remote hook.

// server/middleware/csrf.js
const csrf = require('csurf');
const cookieParser = require('cookie-parser');
app.use(cookieParser());
const csrfProtection = csrf({ cookie: true });

// Apply CSRF protection to relevant routes
app.post('/api/transactions', csrfProtection, (req, res) => {
  // req.csrfToken() must be sent in a header or body by the client
  if (req.headers['x-csrf-token'] !== req.csrfToken()) {
    return res.status(403).json({ error: 'Invalid CSRF token' });
  }
  // proceed with business logic
  res.json({ success: true });
});

// In the browser, include the CSRF token in a header for fetch requests
// fetch('/api/transactions', {
//   method: 'POST',
//   credentials: 'include',
//   headers: { 'Content-Type': 'application/json', 'x-csrf-token': csrfToken },
//   body: JSON.stringify({ amount: 100 })
// });

3. Validate the Authorization header and avoid leaking tokens in URLs

Ensure Bearer tokens are transmitted only in headers and never in query strings or fragments. Add a request preprocessor in Loopback to reject malformed or missing tokens.

// server/remote-config.json
{
  "restApiRoot": "/api",
  "host": "0.0.0.0",
  "middleware": {
    "initial": [
      "loopback#token-validator"
    ]
  }
}

// server/middleware/token-validator.js
module.exports = function tokenValidator(ctx, next) {
  const auth = ctx.req.headers.authorization;
  if (!auth || !auth.startsWith('Bearer ')) {
    const err = new Error('Unauthorized: Bearer token required');
    err.statusCode = 401;
    return next(err);
  }
  const token = auth.slice(7);
  if (!token || token.trim() === '') {
    const err = new Error('Unauthorized: Invalid Bearer token');
    err.statusCode = 401;
    return next(err);
  }
  // Optionally validate token format or scope here
  return next();
};

// Example of a secure endpoint that expects Bearer token in header
app.get('/api/profile', tokenValidator, (req, res) => {
  // Profile logic here
  res.json({ user: 'safe-user-data' });
});

4. Set HttpOnly and Secure flags on cookies if storing refresh tokens

If you use cookies to persist refresh tokens for silent re-authentication, mark them HttpOnly and Secure to reduce exposure to token theft via XSS, which would complement clickjacking defenses.

app.use(cookieParser());
app.set('trust proxy', 1); // behind proxies
res.cookie('refreshToken', refreshTokenValue, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  maxAge: 7 * 24 * 60 * 60 * 1000
});

Frequently Asked Questions

Does using Bearer tokens in the Authorization header fully protect against clickjacking in Loopback?
No. Bearer tokens in headers do not prevent clickjacking if the browser automatically includes them in embedded requests. You must enforce anti-CSRF measures and frame-ancestors/CSP policies to mitigate UI-based attacks.
Can middleBrick detect missing anti-clickjacking protections in a Loopback API?
middleBrick scans unauthenticated attack surfaces and returns security risk scores with findings. It can surface missing security headers and weak framing controls as part of its checks, providing prioritized remediation guidance.