Skip to content

Commit

Permalink
readd X-CSRFToken header to jquery requests
Browse files Browse the repository at this point in the history
  • Loading branch information
Kakadus committed Jun 10, 2024
1 parent 5d978ce commit f75423c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
16 changes: 16 additions & 0 deletions evap/static/ts/src/csrf-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,24 @@ function getCookie(name: string): string | null {
const csrftoken = getCookie("csrftoken")!;
export const CSRF_HEADERS = { "X-CSRFToken": csrftoken };

function isMethodCsrfSafe(method: string): boolean {
// these HTTP methods do not require CSRF protection
return ["GET", "HEAD", "OPTIONS", "TRACE"].includes(method);
}

// setup ajax sending csrf token. Needed by sortablejs
$.ajaxSetup({
beforeSend: function (xhr: JQuery.jqXHR, settings: JQuery.AjaxSettings) {
const isMethodSafe = settings.method && isMethodCsrfSafe(settings.method);
if (!isMethodSafe && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
});

(globalThis as any).CSRF_HEADERS = CSRF_HEADERS;

export const testable = {
getCookie,
isMethodCsrfSafe,
};
26 changes: 25 additions & 1 deletion evap/static/ts/tests/unit/csrf-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ Object.defineProperty(document, "cookie", {
`baz=${encodeURIComponent("+{`")}`,
});

// @ts-ignore
window.$ = require("../../../js/jquery-2.1.3.min");

import { testable } from "src/csrf-utils";

const { getCookie } = testable;
const { getCookie, isMethodCsrfSafe } = testable;

test("parse cookie", () => {
expect(getCookie("foo")).toBe("F00");
Expand All @@ -21,3 +24,24 @@ test("parse cookie", () => {
expect(getCookie("csrftoken")).toBe("token");
expect(getCookie("qux")).toBe(null);
});

test.each(["GET", "HEAD", "OPTIONS", "TRACE"])("method %s is considered safe", method => {
expect(isMethodCsrfSafe(method)).toBe(true);
});

test.each(["POST", "PUT", "DELETE"])("method %s is considered unsafe", method => {
expect(isMethodCsrfSafe(method)).toBe(false);
});

test("send csrf token in request", () => {
const mock = {
open: jest.fn(),
send: jest.fn(),
setRequestHeader: jest.fn(),
};
window.XMLHttpRequest = jest.fn(() => mock) as unknown as typeof window.XMLHttpRequest;

$.post("/receiver");

expect(mock.setRequestHeader).toHaveBeenCalledWith("X-CSRFToken", "token");
});

0 comments on commit f75423c

Please sign in to comment.