Dmitry VerkhoturovandGitHub c9ba8520c7 fix(auth): close OAuth open-redirect by wiring AllowedRedirectHosts (#2049)
* fix(auth): close OAuth open-redirect by wiring AllowedRedirectHosts

Bump go-pkgz/auth/v2 to master (v2.1.2-0.20260421203319-686683f19cf7)
which carries the `from` redirect validator from go-pkgz/auth#275.

The library default with a nil AllowedRedirectHosts is permissive
(preserves legacy behavior for existing consumers on a dep bump), so
just bumping the dep leaves remark42 vulnerable — a crafted
/auth/<provider>/login?from=https://evil.example.com/... still issues
the 307 to the attacker host after the user completes legitimate
OAuth. Verified end-to-end against a local dev-auth instance before
and after this commit.

Wire Opts.AllowedRedirectHosts in getAuthenticator to the operator's
existing --allowed-hosts config, stripping the CSP "self" sentinel
which is not a real hostname. RemarkURL's own host is always implicit
per the library contract, so a default single-site deployment gains
the protection with no config change. Multi-host embeds work as soon
as their embedding hosts are added to AllowedHosts (they already need
to be there for CSP frame-ancestors).

Refreshed vendor tree to match the new module version.

* chore(lint): suppress G703 false positives on image Save

CI's newer gosec flags os.MkdirAll/os.WriteFile in FileSystem.Save with
G703 because id flows in from the caller. id is validated at the HTTP
layer (safePictureSegment in rest_public.go) and dst is derived via
f.location — not a real traversal. Targeted //nolint with reason.

* fix(auth): normalise AllowedRedirectHosts entries + add unit test

Address Copilot review on PR #2049. The previous closure passed raw
s.AllowedHosts entries straight to the auth library, but --allowed-hosts
holds CSP frame-ancestors source expressions: scheme-prefixed values
(https://blog.example.com), entries with ports, and wildcards
(*.cdn.example.com) are all valid there but the auth library compares
against u.Hostname() and would silently drop them — breaking legitimate
redirects on multi-host deployments.

Extract getAllowedRedirectHosts that:
* trims whitespace, drops empty / 'self' / "self" / wildcard entries
* prepends https:// if scheme missing then url.Parse to extract Hostname
* logs a warning on parse failure rather than poisoning the allowlist

Wire the closure in getAuthenticator to call the helper.

Test_getAllowedRedirectHosts covers all the edge cases Copilot flagged
(scheme stripping, port handling, self spellings, wildcards, empty,
mixed real-world).

* fix(auth): preserve explicit port in AllowedRedirectHosts + clarify fs_store nolint

Address Copilot follow-up on PR #2049:

* getAllowedRedirectHosts stripped explicit ports via u.Hostname(), which
  broadened the allowlist. The auth validator checks both Hostname() and
  Host, so an entry like admin.example.com:8443 can and should be kept
  host:port — allowing only that port, not any. Emit u.Host when
  u.Port() != "", u.Hostname() otherwise. Updated tests.

* fs_store Save nolint rationale said "id validated at HTTP layer", but
  Save is reached via image.Service.Save and SaveWithID (cache), neither
  of which is HTTP validation. id is actually a server-generated hash in
  both paths. Updated the comment.
2026-04-21 19:09:26 -05:00
2026-04-16 23:10:05 -05:00
2023-01-08 14:31:36 -06:00
2026-04-12 11:52:57 -05:00
2021-08-09 11:08:42 -05:00
2026-04-16 23:10:05 -05:00
2021-10-09 13:50:50 -05:00

Remark42 Build Status Image Size Go Report Card Coverage Status codecov

Remark42 is a self-hosted, lightweight and simple (yet functional) comment engine, which doesn't spy on users. It can be embedded into blogs, articles, or any other place where readers add comments.

  • Social login via Google, Facebook, Microsoft, GitHub, Apple, Yandex, Patreon, Discord, Telegram and custom OAuth2 providers
  • Login via email
  • Optional anonymous access
  • Multi-level nested comments with both tree and plain presentations
  • Import from Disqus and WordPress
  • Markdown support with friendly formatter toolbar
  • Moderator can remove comments and block users
  • Voting, pinning and verification system
  • Sortable comments
  • Images upload with drag-and-drop
  • Extractor for recent comments, cross-post
  • RSS for all comments and each post
  • Telegram, Slack, Webhook and email notifications for Admins (get notified for each new comment)
  • Email and Telegram notifications for users (get notified when someone responds to your comment)
  • Export data to JSON with automatic backups
  • No external databases, everything embedded in a single data file
  • Fully dockerized and can be deployed in a single command
  • Self-contained executable can be deployed directly to Linux, Windows and macOS
  • Clean, lightweight and customizable UI with white and dark themes
  • Multi-site mode from a single instance
  • Integration with automatic SSL (direct and via nginx-le)
  • Privacy focused

Demo site available with all authentication methods, including email auth and anonymous access.

Screenshots

Comments example:

For admin screenshots see Admin UI documentation

All remark42 documentation is available by the link.

Contribution

In order to start and work on the project locally in development mode check our contribution documentation for backend and frontend.

If you are interested in adding a new localization please check these docs.

S
Description
No description provided
Readme MIT
43 MiB
Languages
Go 69.4%
TypeScript 22.8%
CSS 3.2%
HTML 1.3%
JavaScript 1.3%
Other 2%