Skip to content

security: tighten the app-wide Referrer-Policy so third-party images stop leaking the instance origin #383

Description

@hokiepokedad2

Context

Follow-up from #242 / #382. That PR added referrerpolicy="no-referrer" to the four <img> tags in gym-picker.component.html. The same leak exists everywhere else the app loads a remote image, and annotating tags one at a time doesn't scale.

Problem

Remote image hosts currently receive the origin of every PoracleWeb instance a user browses:

  • uiconsraw.githubusercontent.com/whitewillem/PogoAssets/main/uicons (icon.service.ts:5, DEFAULT_UICONS; operator-overridable, so possibly a self-hosted mirror). Used across the Pokémon, raid, egg, lure, invasion, gym and quick-pick lists and dialogs.
  • Discord avatarscdn.discordapp.com (discord-avatar.component.ts:26, :99, admin-users.component.html:58).
  • Google Fontsfonts.googleapis.com / fonts.gstatic.com stylesheets and font files (index.html).

For a private or invite-only instance the hostname is itself the thing worth not disclosing. Low severity, same as #242 — this is hygiene, not an open hole.

Correction to the follow-up note in #382

That PR suggested <meta name="referrer" content="no-referrer"> in index.html. Don't do that. Two findings from looking at it properly:

1. A policy is already set, server-side. Program.cs:382 sends Referrer-Policy: strict-origin-when-cross-origin in the security-headers middleware. A meta tag would be a second, competing declaration of the same policy in a different file — a maintenance trap. The single point of change is that header.

2. no-referrer would break OAuth login redirects. AuthController reads Request.Headers.Referer in three places — DiscordLogin (:85), the OIDC login path (:263), and OIDC RP-initiated logout (:312) — to recover the frontend origin, validate it against the configured CORS origins, and redirect back there after the provider callback. Under no-referrer those reads return nothing and origin silently falls back to selfOrigin.

Where the SPA and API share a host that fallback is identical and harmless. It is not harmless in the split-origin setup — Angular dev server on one port, API on another — where the user would be bounced to the API's own origin after login instead of back to the dev server. Set as a meta tag it breaks in exactly that topology, because index.html is our document regardless of who serves it.

Suggested fix

Change one line in Program.cs:382:

headers["Referrer-Policy"] = "same-origin";

same-origin sends the full referrer on same-origin requests — so the three AuthController reads keep working in the shared-host deployment — and sends nothing cross-origin, which kills every leak listed above in one place. No per-element attributes, no meta tag, no new config.

Split-origin dev is unaffected either way: the policy governing a request is the one carried by the document making it, and in dev that document comes from the Angular dev server, which sets no policy — so the browser default (strict-origin-when-cross-origin) applies and AuthController still receives the origin it needs.

Worth stating plainly: browsers have defaulted to strict-origin-when-cross-origin for years, so what leaks today is the origin, not full URLs. This closes the remainder rather than plugging a hole.

Acceptance

  • Referrer-Policy header changed to same-origin.
  • Login and logout redirects verified in both topologies: SPA served by the API host, and the split-origin dev setup.
  • uicons, Discord avatars and Google Fonts confirmed still rendering (none of them require a referrer).
  • Decide whether the now-redundant per-element referrerpolicy attributes from security: stop gym-picker images leaking a Referer to third-party hosts (#242) #382 stay. Keeping them is harmless and they're defence-in-depth if the header is ever relaxed; my inclination is to leave them.
  • A security-headers test asserting the value, if one exists to extend.

Files

  • Applications/Pgan.PoracleWebNet.Api/Program.cs — security-headers middleware, line 382
  • Applications/Pgan.PoracleWebNet.Api/Controllers/AuthController.cs — the three Referer reads to regression-test (:85, :263, :312)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions