From 1776b222932f2ba8404401cb5980a07f79ca9627 Mon Sep 17 00:00:00 2001 From: Dane Murphy Date: Mon, 1 Dec 2025 22:07:28 -0800 Subject: [PATCH 1/2] Add clarification to API behavior with respect to CSRF and cookies Signed-off-by: Dane Murphy --- docs/api/auth.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/api/auth.md b/docs/api/auth.md index db8125c54..2c4b952f1 100644 --- a/docs/api/auth.md +++ b/docs/api/auth.md @@ -32,9 +32,12 @@ To get a session ID, you will have to send a `POST` request to the `/api/auth` e xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { - console.log(this.responseText); + console.log(JSON.parse(this.responseText)); } }); + + xhr.open("POST", "https://pi.hole/api/auth"); + xhr.send(data); ``` === "JavaScript (jQuery)" @@ -138,7 +141,7 @@ Once you have a valid SID, you can use it to authenticate your requests. You can 3. In the `X-FTL-SID` header: `X-FTL-SID: vFA+EP4MQ5JJvJg+3Q2Jnw=` 4. In the `sid` cookie: `Cookie: sid=vFA+EP4MQ5JJvJg+3Q2Jnw=` -Note that when using cookie-based authentication, you will also need to send a `X-FTL-CSRF` header with the CSRF token that was returned when you authenticated. This is to prevent a certain kind of identity theft attack the Pi-hole API is immune against. +> Note that when using cookie-based authentication, you will also need to send a `X-CSRF-TOKEN` header with the CSRF token that was returned when you authenticated. This is to prevent a certain kind of identity theft attack the Pi-hole API is immune against. Also note that the API checks for a session ID in the cookie header before checking the request URI. Setting the session ID in the request URI is meaningless in cases where the browser automatically sets the session ID in the cookie header. ???+ example "Authentication with SID" @@ -159,7 +162,6 @@ Note that when using cookie-based authentication, you will also need to send a ` payload = {} headers = { "X-FTL-SID": "vFA+EP4MQ5JJvJg+3Q2Jnw=", - "X-FTL-CSRF": "Ux87YTIiMOf/GKCefVIOMw=" } response = requests.request("GET", url, headers=headers, data=payload, verify=False) @@ -179,8 +181,9 @@ Note that when using cookie-based authentication, you will also need to send a ` } }); - xhr.open("GET", "https://pi.hole/api/dns/blocking?sid=vFA+EP4MQ5JJvJg+3Q2Jnw="); - xhr.setRequestHeader("X-FTL-CSRF", "Ux87YTIiMOf/GKCefVIOMw="); + // The browser sets the "Cookie: sid=vFA+EP4MQ5JJvJg+3Q2Jnw=" header automatically + xhr.open("GET", "https://pi.hole/api/dns/blocking"); + xhr.setRequestHeader("X-CSRF-TOKEN", "Ux87YTIiMOf/GKCefVIOMw="); xhr.send(data); ``` @@ -195,7 +198,6 @@ Note that when using cookie-based authentication, you will also need to send a ` contentType: "application/json", headers: { "X-FTL-SID": "vFA+EP4MQ5JJvJg+3Q2Jnw=", - "X-FTL-CSRF": "Ux87YTIiMOf/GKCefVIOMw=" } }).done(function(data) { console.log(data); @@ -210,7 +212,7 @@ Note that when using cookie-based authentication, you will also need to send a ` **Headers** - If you use cookie-based authentication, you will also need to send a `X-FTL-CSRF` header with the CSRF token that was returned when you authenticated. + If you use cookie-based authentication, you will also need to send a `X-CSRF-TOKEN` header with the CSRF token that was returned when you authenticated. ## Authentication with 2FA @@ -248,9 +250,12 @@ If you have 2FA enabled for your Pi-hole, you will need to provide a TOTP token xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { - console.log(this.responseText); + console.log(JSON.parse(this.responseText)); } }); + + xhr.open("POST", "https://pi.hole/api/auth"); + xhr.send(data); ``` === "JavaScript (jQuery)" @@ -359,7 +364,9 @@ To end your session before the SID expires, you can send a `DELETE` request to t } }); - xhr.open("DELETE", "https://pi.hole/api/auth?sid=vFA+EP4MQ5JJvJg+3Q2Jnw="); + // The browser sets the "Cookie: sid=vFA+EP4MQ5JJvJg+3Q2Jnw=" header automatically + xhr.open("DELETE", "https://pi.hole/api/auth"); + xhr.setRequestHeader("X-CSRF-TOKEN", "Ux87YTIiMOf/GKCefVIOMw="); xhr.send(data); ``` From 5480a8656b87a713b6f4686e79371b9f0d124d1c Mon Sep 17 00:00:00 2001 From: Dane Murphy Date: Tue, 2 Dec 2025 13:50:09 -0800 Subject: [PATCH 2/2] Consistently parse JSON output in JavaScript examples --- docs/api/auth.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/auth.md b/docs/api/auth.md index 2c4b952f1..35a58ac80 100644 --- a/docs/api/auth.md +++ b/docs/api/auth.md @@ -177,7 +177,7 @@ Once you have a valid SID, you can use it to authenticate your requests. You can xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { - console.log(this.responseText); + console.log(JSON.parse(this.responseText)); } }); @@ -360,7 +360,7 @@ To end your session before the SID expires, you can send a `DELETE` request to t xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { - console.log(this.responseText); + console.log(JSON.parse(this.responseText)); } });