Commit Graph
141 Commits
Author SHA1 Message Date
Dmitry VerkhoturovandUmputun f8ba38779b fix(api): require explicit ?site= in matchSiteID middleware
matchSiteID guarded most authenticated and admin routes with
`if siteID != "" && user.SiteID != siteID`. Dropping the ?site= query
parameter made the check no-op and any authenticated user passed the
middleware. Downstream handlers fell back to reading site from the JSON
body or just used the empty string, so on email/telegram subscribe
endpoints (which read site from body) a user authenticated to siteA
could perform actions targeting siteB without the cross-site guard
ever firing.

Require ?site= to be present and to match user.SiteID. Body-only site
flows are still supported provided the URL also carries the matching
?site= — both must agree, which removes the bypass and keeps the
declared site visible to the middleware.

Reproduction TestRest_matchSiteID enumerates four cases (matching,
mismatched, missing, empty). Existing test calls that relied on the
implicit pass had to add ?site=remark42 to the URL: the addComment
helper now derives the param from c.Locator.SiteID, picture upload
URL gets the param explicitly, and the email/telegram subscribe table
adds it to every endpoint. The negative cases that previously asserted
StatusBadRequest from the handler now correctly assert StatusForbidden
from the middleware.
2026-04-17 19:35:50 -05:00
Dmitry VerkhoturovandGitHub ba7c3aed94 refactor: modernise Go code with go fix and manual improvements (#2027)
Apply go fix ./... analysers (Go 1.26) across backend and examples:
- interface{} → any (type alias, no behaviour change)
- for i := 0; i < N; i++ → for range N / for i := range N
- slices.Contains / slices.ContainsFunc replacing manual loops
- strings.SplitSeq replacing strings.Split in range (avoids allocation)
- strings.CutPrefix replacing HasPrefix+TrimPrefix
- min() replacing manual if/else
- fmt.Appendf replacing []byte(fmt.Sprintf(...))
- strings.Builder replacing string += concatenation
- wg.Go(func(){}) replacing wg.Add(1)/go/wg.Done() pattern
- removed redundant ii := i loop variable copies (unnecessary since Go 1.22)

omitempty on struct-typed JSON fields: go fix removed omitempty from
struct-typed fields (time.Time, PostInfo, UserDetailEntry) because
encoding/json's omitempty never applied to struct types — it was always
a no-op. Kept as bare tags (no omitzero replacement) to preserve the
existing serialisation behaviour.
2026-03-25 16:42:37 -05:00
Umputun aca0cff399 fix: IPv6 address truncation and image proxy SSRF vulnerabilities
Replace strings.Split(RemoteAddr, ":") with net.SplitHostPort for correct
IPv6 address extraction in vote deduplication and comment IP tracking.

Harden image proxy: add SSRF-safe transport blocking private/reserved IPs
at connection time with DNS rebinding protection, sanitize error messages
to prevent information leakage, add response size limit via io.LimitReader.

Fix shadowed error variables in BlockedUsers, SetTitle, and Delete methods.
Exclude gosec taint analysis false positives at linter config level.
2026-02-28 04:13:07 -06:00
Dmitry VerkhoturovandUmputun 78d6de6bce Add X-Content-Type-Options and Referrer-Policy security headers
Add two missing security headers to the existing securityHeadersMiddleware:

- X-Content-Type-Options: nosniff — prevents browsers from MIME-sniffing
  responses away from the declared Content-Type, stopping e.g. a
  user-uploaded image from being reinterpreted as executable HTML/JS

- Referrer-Policy: strict-origin-when-cross-origin — limits URL information
  leaked in the Referer header on cross-origin requests to just the origin
  (no path), and sends nothing at all on HTTPS-to-HTTP downgrades
2026-02-21 20:14:44 -06:00
Dmitry VerkhoturovandUmputun bc612ddf81 Remove redundant frame ancestors log from middleware
The log message was printed on every request when allowed ancestors
were configured, creating unnecessary noise in the logs.
2025-12-04 11:15:06 -06:00
Dmitry VerkhoturovandUmputun 658bf307b1 Add mailto: to CSP frame-src directive
Allow mailto links on the deleteme page to work without being blocked
by Content Security Policy.
2025-12-04 11:13:50 -06:00
Dmitry VerkhoturovandGitHub 564e8ff316 Update go dependencies (#1972) 2025-12-03 19:47:01 -06:00
Dmitry VerkhoturovandGitHub baf0db1947 Get rid of github.com/go-chi/render use (#1919)
Replace go-chi/render with go-pkgz/rest for JSON responses and custom
helpers for HTML/plain text responses.

Key changes:
- Replace render.JSON/render.Status with rest.RenderJSON and explicit
  w.WriteHeader() calls
- Replace render.DecodeJSON with json.NewDecoder().Decode()
- Add SendErrorJSON helper that sets Content-Type header before
  WriteHeader (required since rest.RenderJSON can't set headers after
  WriteHeader is called)
- Add HTMLResponse and PlainTextResponse helpers

Fix export double-execution in migrator.go:
The original code called Export twice - once to io.Discard to check for
errors, then again to actually write. This was wasteful and had a race
condition risk. Now file mode buffers to memory first for atomic
success/failure, while stream mode writes directly with proper error
handling.
2025-12-03 11:41:29 -06:00
Dmitry Verkhoturov e3ad01b555 migrate to go-pkgz/auth/v2 2024-12-09 01:54:03 +00:00
Dmitry VerkhoturovandUmputun 6140d82eb2 Fix CSP img-src directive to allow everything without proxy
Change the default img-src value to "*" and sets it to "'self'" when
image proxy is enabled. The previous state was inversion of this logic
which was wrong.
2024-10-20 15:55:51 -05:00
Dmitry VerkhoturovandUmputun f9d4837567 Add Content-Security-Policy and Permissions-Policy headers
`Content-Security-Policy` now restricts resource loading and execution
to enhance security:
  - `default-src 'none'`: Disallow all resource loading by default.
  - `base-uri 'none'`: Prevents the use of `<base>` tag to change the
  base URL for relative URLs.
  - `form-action 'none'`: Disallows form submissions.
  - `connect-src 'self'`: Restricts the origins that can be connected to
   (via XHR, WebSockets, etc.) to the same origin.
  - `frame-src 'self'`: Restricts the origins that can be embedded using
   `<frame>` and `<iframe>` to the same origin (for `/web/` demo
    endpoint).
  - `frame-ancestors %s;`: Specifies the origins that are allowed to
  embed this content in a frame. If no specific origins are allowed, it
  defaults to `*` (any origin). This enhances security by controlling
  which sites can embed your content.
  - `img-src 'self'`: Allows images to be loaded only from the same
  origin. If `imageProxyEnabled` is true, allows images from any origin
  (`*`).
  - `script-src 'self' 'unsafe-inline'`: Allows scripts to be loaded and
   executed only from the same origin and allows inline scripts.
  - `style-src 'self' 'unsafe-inline'`: Allows styles to be loaded and
  applied only from the same origin and allows inline styles.
  - `font-src data:`: Allows fonts to be loaded from data URIs.
  - `object-src 'none'`: Disallows the use of `<object>`, `<embed>`, and
   `<applet>` tags.

`Permissions-Policy` now restricts the use of certain browser features
which we don't use to enhance user privacy and security:
  - `accelerometer=()`: Disables the use of the accelerometer sensor.
  - `autoplay=()`: Disables automatic playback of media.
  - `camera=()`: Disables the use of the camera.
  - `cross-origin-isolated=()`: Disallows the page from being treated as
   cross-origin isolated.
  - `display-capture=()`: Disables the ability to capture the display.
  - `encrypted-media=()`: Disables the use of Encrypted Media Extensions
  .
  - `fullscreen=()`: Disables the ability to use fullscreen mode.
  - `geolocation=()`: Disables the use of geolocation.
  - `gyroscope=()`: Disables the use of the gyroscope sensor.
  - `keyboard-map=()`: Disables the use of the keyboard map.
  - `magnetometer=()`: Disables the use of the magnetometer sensor.
  - `microphone=()`: Disables the use of the microphone.
  - `midi=()`: Disables the use of the MIDI API.
  - `payment=()`: Disables the Payment Request API.
  - `picture-in-picture=()`: Disables the use of Picture-in-Picture mode
  .
  - `publickey-credentials-get=()`: Disables the use of the Web
  Authentication API.
  - `screen-wake-lock=()`: Disables the ability to prevent the screen
  from dimming.
  - `sync-xhr=()`: Disables synchronous XMLHttpRequest.
  - `usb=()`: Disables the use of the USB API.
  - `xr-spatial-tracking=()`: Disables the use of spatial tracking in
  WebXR.
  - `clipboard-read=()`: Disables the ability to read from the clipboard
  .
  - `clipboard-write=()`: Disables the ability to write to the clipboard
  .
  - `gamepad=()`: Disables the use of the Gamepad API.
  - `hid=()`: Disables the use of the Human Interface Device API.
  - `idle-detection=()`: Disables the ability to detect idle state.
  - `interest-cohort=()`: Disables the use of interest cohort tracking.
  - `serial=()`: Disables the use of the Serial API.
  - `unload=()`: Disables the ability to use the `beforeunload` and
  `unload` events.
  - `window-management=()`: Disables the ability to use window
  management APIs.
2024-10-15 17:53:12 -05:00
Umputun 8df986e70a Add content type check for images endpoint
A check in image proxy for validating content type of requested images added. Modified the related tests to accommodate these changes.
2024-07-01 14:47:25 -05:00
Dmitry VerkhoturovandUmputun e5743185b0 collect /find Info for tree and plain types consistently
MakeTree calculated Info locally for historical reasons,
and the results were consistent with the dataService.Info call
but calculated differently.

That change fixes that, ensuring that Info is requested
in the same manner.
2024-03-16 12:49:45 -05:00
Dmitry VerkhoturovandUmputun 1313dee829 update to lcw v2 with generic types 2024-02-20 14:15:35 -06:00
Dmitry VerkhoturovandUmputun d143932924 add MIN_COMMENT_SIZE parameter 2023-12-02 12:16:26 -06:00
Dmitry Verkhoturov dcc7613409 allow disabling fancy HTML formatting
It might be necessary if the comments should preserve
original quotes instead of replacing them with angled ones.
2023-11-26 09:13:53 +01:00
Dmitry VerkhoturovandUmputun 136d7e8215 switch from telegram_bot_username to telegram_notifications
Bot username is returned as an answer to subscribe request,
so knowing it in advance is unnecessary.
2023-06-29 10:52:00 -05:00
Dmitry VerkhoturovandUmputun 596b1045bd allow dots in site id during email user validation 2022-11-03 16:31:00 -05:00
Dmitry VerkhoturovandUmputun 695d0ea13a allow dashes in site ID when validating email auth request
As discovered in #1477, dashes are expected to work in the site ID
and do work everywhere but in email auth. That change makes
the behaviour consistent: site ID now allows dashes.
2022-09-12 17:16:22 -05:00
Umputun cb98885e1f add warn log on rejected email auth validation https://github.com/umputun/remark42/discussions/1139#discussioncomment-3409701 2022-08-16 17:10:09 -04:00
Dmitry VerkhoturovandUmputun a9836aaea0 move static web files from rakyll/statik to go:embed
There is no need for the rakyll/statik package starting with Go 1.16,
which provides us with tools for embedding files
without third-party libraries.
2022-08-03 15:41:02 -05:00
Dmitry Verkhoturov 86d059bf99 move templates from rakyll/statik to go:embed
There is no need for the rakyll/statik package starting with Go 1.16,
which provides us with tools for embedding files
without third-party libraries.
2022-07-29 19:07:49 +02:00
Dmitry Verkhoturov 63a2bdea48 get rid of getstarted.html mentions
umputun introduced that reference in 70649b271,
but I can't find any references to it or the file itself now.
2022-07-27 23:22:08 +02:00
Dmitry VerkhoturovandUmputun 50785e0577 bump didip/tollbooth from v6 to v7 2022-07-19 17:13:02 -05:00
Umputun 6f81bf00e8 add validation for email and site 2022-06-05 11:57:51 -05:00
Umputun 86a1f5ee5d exact match on email login path 2022-06-05 11:57:51 -05:00
Umputun 5121c48c31 reduce max limiter for /auth to 2r/s 2022-06-05 11:57:51 -05:00
Umputun 5f8e16cbe2 add email auth validation with middleware 2022-06-05 11:57:51 -05:00
Dmitry VerkhoturovandUmputun ba86db1263 replace errors package with fmt.Errorf
https://gist.github.com/Peltoche/60b8b81dfbf70164d0e2b88988003229
was used for it, thanks to @Peltoche for publishing it.
2022-04-26 00:25:09 -05:00
Dmitry VerkhoturovandUmputun 2a7966b9e6 replace numbers with proper HTTP status codes in tests
Also, remove unneeded whitespaces using whitespace
linter for golangci-lint.
2022-04-17 19:42:45 -05:00
Umputun 65e3a82d8b add no-signature mode suppressing app info middleware #1305 2022-04-05 12:08:44 -05:00
Dmitry VerkhoturovandUmputun 603decabf6 add QR API endpoint for Telegram auth and notifications
Telegram authentication requires you to open a chat on the phone.
It's convenient to have a QR code for the case when you want to
log in on the computer but have Telegram only on your phone
and would be able to scan the QR instead of copy-pasting the link
from the computer to the phone any other way.

Originally we thought of generating QR on the client but found
backend-generated QR a better alternative because we avoid adding
one more JavaScript dependency to the frontend that way.
2022-01-31 14:28:18 -06:00
Dmitry VerkhoturovandUmputun c027dcd765 enable telegram notify trough writing bot a message
Previously it was done through writing bot first,
clicking a button, copying the token, and pasting
it into the web interface.

The new flow is way simpler: click the link
to write bot a message, then click the "Check"
button in the web UI and you got notifications
enabled.
2021-11-07 11:51:28 -06:00
Dmitry VerkhoturovandUmputun 4793a31075 move previewCommentCtrl to private REST struct 2021-10-16 11:04:03 -05:00
romanilchyshyn df0d4d27fa patreon auth 2021-10-13 00:30:14 +03:00
Dmitry VerkhoturovandUmputun 200733ed03 add user telegram notifications 2021-07-03 14:57:09 -05:00
Umputun 57fc382956 add ability to select listening address #1000 2021-05-13 14:46:52 -05:00
UmputunandGitHub 52fbac904e Admin edit (#997)
* allow admin edits without restrictions

* lint: err reassignment

* lint: suppress false positive

* add admin-edit to readme

* expose admin_edit to config controller
2021-05-10 11:36:02 -05:00
UmputunandGitHub d5246c9689 Deps bump (#956)
* remove redundant sprintf

* bump many deps

* missing vendors
2021-04-27 00:30:38 -05:00
Umputun 6d525e4820 remove no-cache from /api/v1/avatar api 2021-01-15 16:22:45 -06:00
Umputun 12b0fbe75d remove no-cache from /avatar api 2021-01-15 16:18:10 -06:00
Umputun 0dd3cd93ee add no-cache to Cache-Control on static files 2021-01-15 14:55:32 -06:00
Umputun eb21a05b7b add optional frame-ancestors (Content-Security-Policy) for the list of hosts passed by user 2021-01-03 02:33:51 -06:00
Dmitry Verkhoturov 809a7c7dbd Clean unused stream code
It was supposed to solve #253 but frontend part for it in
#357 was never finished, and backend code produces false
positive test failures since day 0. The cost of just having
this code around is too high, we'll re-add it in case
frontend implementation will be finished.
2020-11-30 02:00:59 +01:00
Dmitry VerkhoturovandUmputun 6426ea154e #819 add SendJWTHeader auth option, expose it on /config 2020-11-29 18:18:22 -06:00
Dmitry VerkhoturovandUmputun 1ce3cf3d1f simplify admin email notifications 2020-10-20 11:02:04 -05:00
Dmitry VerkhoturovandUmputun b974fd9cc4 add ability to set multiple admin emails for notifications 2020-09-02 15:09:46 -05:00
Umputun 1eedcc0eb3 don't allow anon with space prefix or suffix 2020-08-16 21:12:42 -05:00
Umputun 729b6d2d08 add --proxy-cors $PROXY_CORS disabling internal cors middleware #749 2020-07-27 16:58:47 -05:00
Dmitry Verkhoturov 80f4862c9c fix leaking goroutines and add tests for them 2020-06-01 09:58:48 +02:00