Skip to content

CSRF token is invalid most of the time #13

Description

@IArnaut2

I made middleware to send a CSRF token to a template and used it globally.
realestate\middleware\csrfToken.ts:

import { Request, Response } from "express";

function csrfToken(req: Request, res: Response, next: any) {
  res.locals.csrfToken = req.csrfToken();
  next();
}

export default csrfToken;

realestate\app.ts:

import csurf from "tiny-csrf";
import csrfToken from "./middleware/csrfToken";

app.use(cookieParser(process.env.COOKIE_SECRET!));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(join(__dirname, "public")));
app.use(
  session({
    secret: process.env.SESSION_SECRET!,
    resave: true,
    saveUninitialized: true
  })
);
app.disable("x-powered-by");

// view engine setup
app.set("view engine", "ejs").set("views", join(__dirname, "views"));

app.use(moment);
// 1 Authentication & authorization
app.use(getAuth);
// 4 CSRF tokens
app.use(csurf(process.env.CSRF_SECRET!));
app.use(csrfToken);
// 7 Security headers
app.use(securityHeaders);

Because not only I use the CSRF token login, register and other forms, but in logout form in a layout too.
realestate\views\partials\header.ejs:

<body class="d-flex flex-column">
  <!-- Navbar -->
  <nav class="navbar navbar-expand-md bg-secondary sticky-top py-0 mx-0 mb-3">
    <div class="container-fluid">
      <!-- ... -->

      <div class="collapse navbar-collapse" id="toggler">
        <!-- ... -->

        <ul class="navbar-nav">
          <!-- 1 Authentication & authorization -->
          <% if (auth) { %>
          <li class="nav-item btn btn-secondary px-md-1 py-md-3">
            <a class="nav-link fw-semibold text-light" href="/korisnici/<%= auth.id %>">Profil</a>
          </li>
          <li class="nav-item btn btn-secondary px-md-1 py-md-3">
            <form action="/odjava" method="post">
              <!-- 4 CSRF tokens -->
              <input type="hidden" name="_csrf" value="<%= csrfToken %>">
              <input class="nav-link fw-semibold text-light" type="submit" value="Odjava">
            </form>
          </li>
          <% } else { %>
          <!-- ... -->
          <% } %>
        </ul>
      </div>
    </div>
  </nav>

  <main class="flex-grow-1">
    <div class="container">

http://localhost:3000/oglasi Response cookies:

<html><body>
<!--StartFragment-->
csrfToken |  
-- | --
expires | "2026-01-26T14:11:08.000Z"
httpOnly | true
path | "/"
samesite | "Strict"
value | "s:959cbef0a8674522e21950723868a348:7859594351832cab4e9f715161af31c3c9c7bb91e1d942a288c64f2b043713d8c3ffc00fbe77574db58305712a0714ca.S9TlbBnPvvfeXtZpJ9rNZ20LwmvoG8MUSpmaVjzRFmQ"

<!--EndFragment-->
</body>
</html>

http://localhost:3000/oglasi Request cookies:

<html><body>
<!--StartFragment-->
connect.sid | "s:aS4KDjoQyl1Sm3tj9A31tbBqub8HWOVj.kDOqaMRrSEi/XLVZKLTx5eTYUI0Fxyx6wtTpA0MoHUM"
-- | --
csrfToken | "s:0c58a4f3cce0f99a3d8264c02c851abd:6981b2d4d637ec8921681b2fbad221ae02d7b5d8cbb73171e1fc5db1da4c540d9252d2a6cc336c2f5967526c9fbc48d9.dajMYcbNKjPbk9sirKbRCl93K4mnQ4ytnqmCoknxaVQ"
jwt | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiaWF0IjoxNzY5NDM1MjQ1LCJleHAiOjE3Njk1MjE2NDV9.Wqce2DDH0FGmgaakDhB3ELKnU00aKdqoz3EqHdm2hFQ"

<!--EndFragment-->
</body>
</html>

But whenever I click the logout button, save button in listing card or post form data, the CSRF token is invalid.
realestate\views\partials\listings\list\card.ejs:

<!-- Card -->
<div class="card mb-3">
  <!-- ... -->

  <%- include("./footer", { authId }) %>
</div>

realestate\views\partials\listings\list\footer.ejs:

<!-- Card footer -->
<div class="card-footer d-flex justify-content-between align-items-center">
  <!-- ... -->

  <form action="/oglasi/cuvanje/<%= listing.id %>" method="post">
    <!-- 4 CSRF tokens -->
    <input type="hidden" name="_csrf" value="<%= csrfToken %>">

    <button class="btn btn-link" type="submit">
      <% if (listing.isSaved(authId)) { %>
      <i class="bi bi-bookmark-fill text-success fs-4"></i>
      <% } else { %>
      <i class="bi bi-bookmark text-success fs-4"></i>
      <% } %>
    </button>
  </form>
</div>

Error:

Error: Did not get a valid CSRF token for 'POST /oglasi/cuvanje/2': 1223a98e-7613-4d3f-9f07-22594f6b4a7a v. undefined

http://localhost:3000/oglasi/cuvanje/2 Request cookies:

<html><body>
<!--StartFragment-->
  |  
-- | --
connect.sid | "s:aS4KDjoQyl1Sm3tj9A31tbBqub8HWOVj.kDOqaMRrSEi/XLVZKLTx5eTYUI0Fxyx6wtTpA0MoHUM"
jwt | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiaWF0IjoxNzY5NDM1MjQ1LCJleHAiOjE3Njk1MjE2NDV9.Wqce2DDH0FGmgaakDhB3ELKnU00aKdqoz3EqHdm2hFQ"

<!--EndFragment-->
</body>
</html>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions