From 23a433f4110d887f3306b89e1e81abe42fbe8f2b Mon Sep 17 00:00:00 2001 From: Paul Nothaft Date: Wed, 2 Sep 2026 09:36:45 +0200 Subject: [PATCH] docs(analytics): state the tracker proxy's trust model The SSRF vetting is resolve-then-fetch and production-only. Say so, and say why that is acceptable: the hostname is admin-controlled, the request is confined to allowlisted paths and carries no PicPeak credentials, and the S3/MinIO client already takes the same posture. --- backend/src/routes/analyticsTrackerProxy.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backend/src/routes/analyticsTrackerProxy.js b/backend/src/routes/analyticsTrackerProxy.js index fbe88312..5e48de4b 100644 --- a/backend/src/routes/analyticsTrackerProxy.js +++ b/backend/src/routes/analyticsTrackerProxy.js @@ -41,6 +41,17 @@ * arbitrary client headers); * - a sanitised response Content-Type plus `nosniff`, so a tracker host * cannot serve HTML/SVG through PicPeak's origin and get it rendered. + * + * The threat model is a TRUSTED admin and a possibly hostile tracker host or + * visitor — not a hostile admin. Two consequences worth knowing: + * - the host check is resolve-then-fetch: the hostname is vetted when the + * config is (re)loaded and `fetch` resolves it again, so a host whose DNS + * is flipped between the two (rebinding) could reach an internal address + * for up to CONFIG_TTL_MS. Only the admin can set that hostname, and the + * request is still confined to the allowlisted paths with no PicPeak + * credentials attached. Same posture as the S3/MinIO client. + * - the check runs in production only, so a development install can point + * at a tracker on localhost. */ const express = require('express');