/docs loads swagger-ui 4.15.5 from cdnjs without SRI, and does not work offline
Author: lbellowsCreated Sep 17, 2026Updated Sep 17, 2026
docs/ui.go serves the Swagger UI page with three external resources from cdnjs:
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui.css" >
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui-bundle.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.15.5/swagger-ui-standalone-preset.js"> </script>Three things follow from that:
- No
integrity/SRI./docsis unauthenticated and shares an origin with the web UI, so anything served from that CDN path runs in the app origin. An SRI hash costs nothing here since the version is already pinned. - 4.15.5 is from 2022, several majors behind swagger-ui 5.x.
/docsdoes not work offline, which is awkward for the air-gapped/LAN deployments Gotify is often used in — the rest of the UI is embedded viago:embed.
Vendoring swagger-ui-dist into ui/ and embedding it would solve all three at once. Would you take a PR for that, or is the CDN a deliberate choice to keep the binary small?
(Unrelated but in the same file: GET /swagger?base=… splices the query value into the spec JSON unescaped (docs/swagger.go:getSwaggerJSON), so a crafted base can break out of the "host" string. It is self-inflicted only — the page passes window.location.host, never a query param — and the response is sniffed as text/plain, so I do not think it is more than cosmetic. Mentioning it in case you want the value validated anyway.)
Source: gotify/server