From 97b14edbaa8c3cd67a18ddd2ac7097464d06182b Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 1 Mar 2026 13:01:06 -0600 Subject: [PATCH] fix(api): skip CSRF for Bearer-authenticated requests --- apps/api/src/common/guards/csrf.guard.spec.ts | 11 +++++++++++ apps/api/src/common/guards/csrf.guard.ts | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/apps/api/src/common/guards/csrf.guard.spec.ts b/apps/api/src/common/guards/csrf.guard.spec.ts index 82c9685..50aa121 100644 --- a/apps/api/src/common/guards/csrf.guard.spec.ts +++ b/apps/api/src/common/guards/csrf.guard.spec.ts @@ -87,6 +87,17 @@ describe("CsrfGuard", () => { }); describe("State-changing methods requiring CSRF", () => { + it("should allow POST with Bearer auth without CSRF token", () => { + const context = createContext( + "POST", + {}, + { authorization: "Bearer api-token" }, + false, + "user-123" + ); + expect(guard.canActivate(context)).toBe(true); + }); + it("should reject POST without CSRF token", () => { const context = createContext("POST", {}, {}, false, "user-123"); expect(() => guard.canActivate(context)).toThrow(ForbiddenException); diff --git a/apps/api/src/common/guards/csrf.guard.ts b/apps/api/src/common/guards/csrf.guard.ts index 805a224..82e0156 100644 --- a/apps/api/src/common/guards/csrf.guard.ts +++ b/apps/api/src/common/guards/csrf.guard.ts @@ -57,6 +57,11 @@ export class CsrfGuard implements CanActivate { return true; } + const authHeader = request.headers.authorization; + if (typeof authHeader === "string" && authHeader.startsWith("Bearer ")) { + return true; + } + // Get CSRF token from cookie and header const cookies = request.cookies as Record | undefined; const cookieToken = cookies?.["csrf-token"]; -- 2.49.1