8224626ed46d10e98d8fee29c9e9e1083a82b12c
readAndValidateImage caps the byte size of incoming images but the resize() helper that follows still called image.Decode unconditionally, allocating pixel memory proportional to the *declared* image dimensions. A ~100 KB compressed PNG or GIF that declares 65535x65535 px forces image.Decode to allocate ~17 GB of raster, OOMing the service on a single comment upload (or on the proxy's CacheExternal path when caching a malicious upstream). Hardening: - maxImagePixels = 16 MP constant. Covers any realistic image (~4096x4096) while bounding peak allocation. - resize() now runs image.DecodeConfig first (cheap, no pixel allocation) to read declared width/height before any full decode. - Multiplication of width × height uses int64 to defeat 32-bit overflow (GOARCH=386, 32-bit arm): on those targets, int(cfg.Width)*int(cfg.Height) could wrap below maxImagePixels and bypass the cap. GIF's 16-bit logical screen and JPEG's 16-bit SOF dimensions both reach this if int-multiplied. - Bytes exceeding the cap, or non-image input that fails DecodeConfig, return nil. prepareImage propagates the rejection as a clear error instead of storing the malformed/oversized data verbatim. - The no-resize-needed path returns the validated original bytes verbatim so animated GIFs round-trip without being flattened to a single frame. The DecodeConfig precheck applies even when MaxWidth/MaxHeight are 0 (resize disabled) — the dimension cap is unconditional defense-in-depth. Two adjacent fixes surfaced by the new resize contract: 1. readAndValidateImage previously did `data[:512]` without a bounds check, panicking on any body shorter than 512 bytes. Now bounded with min(). 2. image/webp was listed as an allowed format but no WebP decoder was registered, so DecodeConfig would refuse legitimate WebP uploads. Added `_ "golang.org/x/image/webp"` (already in go.mod via x/image/draw) so the registered decoders match the allowlist. Tests: - TestService_resizeRejectsDecompressionBomb builds a 14-byte GIF87a header declaring 65535x65535 and asserts resize() refuses it both at the unit level and through SaveWithID end-to-end (no store write). - TestService_SaveWithIDShortPayload regression-tests the short-body panic. - TestService_SaveWithIDWebP regression-tests WebP round-trip through prepareImage with the new DecodeConfig requirement. - TestService_resize subtests updated to assert non-image bytes are now refused (previously the helper fell back to returning the raw bytes verbatim, letting malformed content reach the store).
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%
