HIGH arp spoofingstrapitypescript

Arp Spoofing in Strapi (Typescript)

Arp Spoofing in Strapi with Typescript

In Strapi applications that expose REST APIs over HTTP, an attacker can perform ARP spoofing to intercept traffic between a client and the Strapi server when the network layer lacks proper isolation. This is especially relevant in containerized deployments or cloud environments where multiple tenants share the same NIC or where public-facing APIs are exposed without network segmentation. ARP spoofing allows an attacker to associate their MAC address with the IP address of the Strapi server, causing legitimate client requests to be redirected to the attacker's machine. If the Strapi API uses Typescript for custom controllers or services, and if those implementations rely on unvalidated redirects or lack token-based session binding, the attacker can capture session cookies or JWTs from authenticated users.

For example, consider a Strapi controller that issues a JWT after login and stores it in an HttpOnly cookie:

// src/api/auth/controllers/AuthController.ts
import { Request } from 'hapi';
export async function login(ctx: Request) {
  const { identifier, password } = ctx.request.body;
  const user = await strapi.query('plugin::users-permissions.user').findOne({
    where: { email: identifier }
  });
  if (!user || !(await strapi.service('api::user.user').validatePassword(password, user.password))) {
    return ctx.unauthorized('Invalid credentials');
  }
  const jwt = await strapi.service('api::jwt').create({
    user: { id: user.id }
  });
  ctx.cookies.set('token', jwt, {
    httpOnly: true,
    sameSite: 'strict',
    maxAge: 60 * 60 * 24 * 7 // 1 week
  });
  return ctx.ok({ message: 'Logged in' });
}
This cookie is vulnerable to interception if the connection is compromised via ARP spoofing. An attacker on the same LAN can poison the ARP cache of the client, making it believe the Strapi server is at their MAC address. When the client makes a request to https://api.example.com/api/auth/login, the request is sent to the attacker, who can read the response including the Set-Cookie header. If the client does not validate the server's identity through certificate pinning or public key infrastructure (PKI), the session can be hijacked.

Additionally, if the Strapi API uses attribute-based access control (ABAC) or role-based access control (RBAC) implemented in Typescript services without proper request origin verification, an attacker who successfully intercepts traffic may bypass authorization checks by mimicking a legitimate request from an authenticated user. This is particularly dangerous when APIs expose GraphQL endpoints or custom REST routes that do not enforce strict CORS or CSRF protections. Even though Strapi enforces CSRF tokens by default for POST, PUT, DELETE requests, a man-in-the-middle (MITM) attacker who controls the client's view of the server can still relay requests with valid tokens, especially if the client-side JavaScript does not validate the response's Access-Control-Allow-Origin header or perform additional integrity checks.

Moreover, in TypeScript-based custom logic, developers might inadvertently expose sensitive data through debug endpoints or failed query logging. For instance, if a custom controller logs full request bodies for debugging and does not sanitize input, an ARP spoofing attack that enables request modification (e.g., injecting malicious headers) could trigger error messages that leak internal structure. While Strapi itself does not introduce ARP vulnerabilities, the combination of network exposure in cloud-hosted deployments and custom Typescript logic can amplify the risk of data exfiltration via ARP spoofing.

Typescript-Specific Remediation in Strapi

To mitigate ARP spoofing risks in a Strapi application using Typescript, developers must assume the network is hostile and implement application-layer protections that do not rely solely on infrastructure security. One of the most effective strategies is to enforce HTTPS with HSTS and certificate transparency, ensuring that even if ARP spoofing occurs, the client will detect mismatched certificates and abort the connection. Additionally, JWTs should be issued with short expiration times and rotated frequently, reducing the window of opportunity for session hijacking.

Here is a revised version of the login controller that incorporates secure cookie settings and token binding:

import { Request } from 'hapi';
export async function login(ctx: Request) {
  const { identifier, password } = ctx.request.body;
  const user = await strapi.query('plugin::users-permissions.user').findOne({
    where: { email: identifier }
  });
  if (!user || !(await strapi.service('api::user.user').validatePassword(password, user.password))) {
    return ctx.unauthorized('Invalid credentials');
  }
  const jwt = await strapi.service('api::jwt').create({
    user: { id: user.id }
  });
  // Bind JWT to IP address and User-Agent for added integrity
  const clientIp = ctx.request.ip;
  const userAgent = ctx.request.headers['user-agent'];
  const boundJwt = await strapi.service('api::jwt').bindToContext(jwt, {
    ip: clientIp,
    ua: userAgent
  });
  ctx.cookies.set('token', boundJwt, {
    httpOnly: true,
    sameSite: 'strict',
    maxAge: 60 * 60 * 24, // 1 day
    path: '/',
    secure: true,
    domain: ctx.request.host
  });
  return ctx.ok({ message: 'Logged in' });
}
This approach ensures that if an attacker intercepts a session cookie, it cannot be reused from a different IP or user agent without triggering validation failure. Additionally, all API responses should include Strict-Transport-Security: max-age=31536000; includeSubDomains in headers, which can be configured in config/middleware.js:

module.exports = ({ env }) => ([
  (config, { strapi }) => [
    'strapi::security',
  ],
});
// config/middleware.js
module.exports = ({ env }) => ([
  'strapi::security',
], ({ strapi }) => {
  return async (ctx, next) => {
    const doesRequireHttps = ['/api', '/admin'];
    if (doesRequireHttps.includes(ctx.path) && ctx.request.protocol !== 'https') {
      return ctx.redirect(`https://${ctx.request.host}${ctx.request.url}`);
    }
    await next();
  };
});

Furthermore, developers should avoid logging sensitive information in server logs and ensure that error responses do not expose stack traces or internal structure. Input validation in custom Typescript controllers should use strict schemas, such as those provided by ajv or Strapi's built-in validation, to prevent injection attacks that could be triggered via modified packets during ARP spoofing. By combining network awareness with application-level safeguards, Strapi applications can reduce the impact of ARP spoofing even in compromised network environments.