npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

mini-csrf

v1.0.4

Published

A small, stateless, session-less CSRF protection middleware for Express

Readme

mini-csrf NPM version NPM total downloads

A smol CSRF protection middleware for Express applications using a stateless, session-less, HMAC token.

Introduction

This implementation is probably the smallest possible stateless Cross-Site Request Forgery (CSRF) protection for your Node.js/Express applications that's usably secure. It does not comply with the OWASP.

The use case for it would be when you need light-weight stateless non-session based CSRF protection. If you are using sessions you should use small-csrf instead since it implements an OWASP compliant Double-Submit Cookie Pattern.

Method

The CSRF token is a HMAC hash of the browser user-agent, IP address, the time and a server secret. The token and the time are inserted into the web page that calls a mutating route. The server is able to confirm the correctness of the token by re-creating it, then the time provided is checked to ensure its within the tolerance.

Token comparisons are done in constant time to avoid timing attacks.

Comparisons

| Feature | mini-csrf | Double Submit Cookies | Synchronizer Token | | ------------------------------------- | ------------------------------- | --------------------- | ------------------------------ | | Session required | ❌ | ❌ | ✅ | | Stateless | ✅ | ✅ | ❌ | | Forgery resistance | ✅ (via HMAC) | ✅ (via cross-check) | ✅ (via match to stored value) | | Tied to browser | Partially (IP/UA) | ✅ (via cookie) | ✅ (via session cookie) | | Resistant to replay | ❌ (within time window) | ❌ | ❌ | | Prevents CSRF with stolen cookies | ❌ (attacker can guess context) | ✅ | ✅ |

Installation

npm install mini-csrf

Quick Start

Basic integration with Express:

// npm install express mini-csrf
import express from "express";
import csrfProtection from "mini-csrf";

const app = express();

app.use(express.urlencoded({ extended: false }));
app.use(express.json());

// CSRF protection middleware
const csrf = csrfProtection({
  secret: "at-least-32-characters-long-csrf-secret",
});

app.use(csrf.middleware);

// render a form with CSRF token
// the csrf Token Html actually contains the token and time
app.get("/form", (req, res) => {
  res.send(`
    <form action="/submit" method="POST">
      ${csrf.csrfTokenHtml(req)}
      <input type="text" name="data">
      <button type="submit">Submit</button>
    </form>
  `);
});

app.post("/submit", (req, res) => {
  // if the request reaches here, CSRF validation passed since
  // it's done in the middleware
  res.send("Form submitted successfully!");
});

// handler for CSRF errors
app.use((err, req, res, next) => {
  if (err.code === "EBADCSRFTOKEN") {
    return res.status(403).send("Invalid CSRF token. Form submission failed.");
  }
  next(err);
});

app.listen(3000);

Configuration

The csrfProtection function accepts a configuration object with the following options:

Required Parameters

secret (string)

The server secret used to generate HMAC tokens. Must be at least 32 characters long.

const csrf = csrfProtection({
  secret: "at-least-32-characters-long-csrf-secret",
});

Optional Parameters

fieldNames (object)

Customize the names of the hidden form fields. Default values shown below:

const csrf = csrfProtection({
  secret: "at-least-32-characters-long-csrf-secret",
  fieldNames: {
    token: "_csrf_token", // default
    time: "_csrf_time", // default
  },
});

ttl (number)

Time-to-live for tokens in milliseconds. Tokens older than this will be rejected. Default is 3600000 (1 hour).

const csrf = csrfProtection({
  secret: "at-least-32-characters-long-csrf-secret",
  ttl: 1800000, // 30 minutes
});

Complete Configuration Example

const csrf = csrfProtection({
  secret: "at-least-32-characters-long-csrf-secret",
  fieldNames: {
    token: "csrf_token",
    time: "csrf_timestamp",
  },
  ttl: 900000, // 15 minutes
});

Contributing

Contributions and issues are welcome, especially for security concerns.

Tests

Uses the built-in Node test runner - available from Node 20 npm test to run

Example App

To run a local demo of mini-csrf in an Express app from a cloned repo:

cd example && npm install && npm start

Then visit http://localhost:3000

License

MIT

Versions

  • 1.0.0 - initial
  • 1.0.1 - README fixes
  • 1.0.2 - ReaDmE fIXeS
  • 1.0.3 - types, input validation
  • 1.0.4 - NPM publish via GitHub Action