Information Security 9 min read

CSRF Attack Prevention for Node.js Services: Six Practical Rules and Implementation

This article explains the severe risks of CSRF attacks for web services, debunks common misconceptions, and presents six concrete development rules plus a Koa2 code example to effectively protect Node.js back‑ends, especially in financial applications.

58 Tech
58 Tech
58 Tech
CSRF Attack Prevention for Node.js Services: Six Practical Rules and Implementation

Introduction

Preventing CSRF attacks is crucial for internet companies. Drawing on the practice of 58 Finance, this article shares a comprehensive approach to improve the security of Node.js services.

Background

Cross‑Site Request Forgery (CSRF) allows an attacker to use a victim’s authenticated session to send legitimate‑looking requests to a target server, potentially performing actions such as posting content, making purchases, or transferring money.

For example, a malicious page can embed an image tag like <img src="https://hellobank.com/transfer/money/to/?accountId=6225&money=100" /> , which triggers a GET request that carries the victim’s cookies to the bank’s server, resulting in an unauthorized transfer.

Both GET and POST requests can be forged, and CSRF can be combined with XSS to succeed even without the victim visiting a malicious site.

Common Misconceptions

Many articles suggest checking the HTTP Referrer header or using POST instead of GET, but these only raise the attack difficulty and do not provide true protection.

Effective CSRF defense requires coordinated front‑end JavaScript changes and back‑end validation, along with agreed development rules.

Development Rules (Six Rules)

Rule 1: GET requests do not need CSRF protection because they should never change server state according to HTTP semantics.

Rule 2: Requests that do not carry business‑related cookies do not need CSRF protection, as the server cannot identify the user.

Rule 3: POST requests to URLs on a whitelist can be exempted from CSRF checks (e.g., third‑party callbacks that do not involve a browser).

Rule 4: When the browser sends a POST request, add a CSRF token to the request header, calculated from the business cookie.

Rule 5: The server validates that the CSRF token in the header matches the one derived from the cookie.

Rule 6: Use a dedicated CSRF cookie (separate from the business cookie) that is sufficiently random and not predictable, especially when the business cookie is HttpOnly.

Specific Implementation

The following Koa2‑based code demonstrates the core logic. The function returns true when a CSRF attack is detected.

function isCsrfAttack(ctx) {
  const csrfHeader = ctx.get('csrf');
  const businessCookie = ctx.cookies.get('session');
  const expectedToken = generateTokenFromCookie(businessCookie);
  return csrfHeader !== expectedToken;
}

app.use(async (ctx, next) => {
  if (ctx.method === 'POST' && isCsrfAttack(ctx)) {
    ctx.status = 403;
    ctx.body = 'CSRF detected';
    return;
  }
  await next();
});

Place this middleware before the POST route handlers in Koa’s onion model. Additional measures such as rate limiting or IP restrictions can be added as needed.

Author

Jia Jianrong, Front‑End Lead at 58 Finance, responsible for the architecture and construction of financial middle‑ and back‑office systems.

Recommended Reading

Links to related articles on micro‑frontends, front‑end scaffolding, Netty memory pool, and deep‑learning platform optimization are provided for further exploration.

backendwebNode.jsSecurityCSRFKoa
58 Tech
Written by

58 Tech

Official tech channel of 58, a platform for tech innovation, sharing, and communication.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.