Skip to content

fix: remove SSRF sinks from API failure logging#2665

Merged
enoch85 merged 2 commits into
developmentfrom
fix/codeql-ssrf-log-sinks
Apr 12, 2026
Merged

fix: remove SSRF sinks from API failure logging#2665
enoch85 merged 2 commits into
developmentfrom
fix/codeql-ssrf-log-sinks

Conversation

@enoch85

@enoch85 enoch85 commented Apr 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes the critical CodeQL js/server-side-request-forgery alert on external-api.service.ts that was blocking #2664.

The alert fired because axios.getUri({ ...config, url: endpoint }) was called purely to build a string for failure log messages. CodeQL treats getUri as a URL-construction sink, so user-provided endpoint flowing into it lit up as SSRF — even though the result only ever reached logger.debug.

Changes

  • New lib/requestLogging.tsdescribeRequestTarget(fallbackBaseURL, endpoint, config?): builds a log-safe base + path + query string with plain string ops and encodeURIComponent. No URL parser, no getUri.
  • external-api.service.ts: logRequestFailure and postRolling use the helper. Per-request baseURL overrides and config.params are still reflected in failure logs.
  • lib/plexApi.ts: same helper on the error path.

Every subclass of ExternalApiService (servarr, seerr, tautulli, tmdb, tvdb, plextv, plexCommunity, internal) inherits the fix automatically.

Notes

  • Log format is unchanged and now preserves per-request context (plextv metadata.provider.plex.tv baseURL overrides, tautulli cmd=... params) that a naive fix would have lost.
  • No request-path behavior change — only how the target string is built for logs.
  • An earlier iteration added a normalizeExternalApiBaseUrl helper using new URL(baseUrl). CodeQL treated that as a new URL-construction sink and started flagging every downstream axios request. Reverted to keep the fix minimal.

Test plan

  • Server tests pass (external-api, plex-api, jellyfin-adapter specs)
  • yarn build green
  • yarn format:check green
  • CodeQL re-run confirms the SSRF alert is cleared with no new findings

enoch85 added 2 commits April 12, 2026 09:08
Replace axios.getUri() calls in external-api, plexApi, and jellyfin-adapter
with a small helper that builds log-safe request descriptors via plain
string ops, and normalize base URLs on construction. Preserves per-request
baseURL overrides and params in failure logs, and closes the CodeQL
server-side-request-forgery alert on external-api.service.ts.
The added normalizeExternalApiBaseUrl used new URL(baseUrl), which CodeQL
treats as a URL-construction sink. That gave its SSRF query a cleaner
dataflow path from user config into every downstream axios request,
producing four new alerts on the request call sites in
external-api.service.ts. Removing the normalizer keeps only
describeRequestTarget, which builds log strings via plain string ops
and encodeURIComponent, and closes the original alert without introducing
new ones.
@enoch85 enoch85 merged commit ea77a31 into development Apr 12, 2026
13 checks passed
@enoch85 enoch85 deleted the fix/codeql-ssrf-log-sinks branch April 12, 2026 09:20
maintainerr-automation Bot added a commit that referenced this pull request Apr 12, 2026
* fix: quiet noisy service logs

* fix: clarify rule placeholders and Seerr helper copy

* fix: track collection membership provenance (#2663)

* fix: remove SSRF sinks from API failure logging (#2665)

* fix: remove SSRF sinks from API failure logging

Replace axios.getUri() calls in external-api, plexApi, and jellyfin-adapter
with a small helper that builds log-safe request descriptors via plain
string ops, and normalize base URLs on construction. Preserves per-request
baseURL overrides and params in failure logs, and closes the CodeQL
server-side-request-forgery alert on external-api.service.ts.

* fix: drop base URL normalizer to keep CodeQL SSRF fix minimal

The added normalizeExternalApiBaseUrl used new URL(baseUrl), which CodeQL
treats as a URL-construction sink. That gave its SSRF query a cleaner
dataflow path from user config into every downstream axios request,
producing four new alerts on the request call sites in
external-api.service.ts. Removing the normalizer keeps only
describeRequestTarget, which builds log strings via plain string ops
and encodeURIComponent, and closes the original alert without introducing
new ones.

---------

Co-authored-by: enoch85 <mailto@danielhansson.nu>
@maintainerr-automation

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.6.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant