c9ba8520c7e8c84f745dd166ea38ae7c43fc43c9
* 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.
Remark42

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.
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.
Related projects
Languages
Go
69.4%
TypeScript
22.8%
CSS
3.2%
HTML
1.3%
JavaScript
1.3%
Other
2%
