mirror of
https://github.com/ether/etherpad-lite.git
synced 2026-07-17 16:47:05 +00:00
* security: allow integrator sessionID cookie to be HttpOnly (#7045) The integrator-set sessionID cookie was forced to be non-HttpOnly because Etherpad's own client JS read it via document.cookie and forwarded it in the socket.io CLIENT_READY payload, exposing it to XSS. Mirror the GDPR PR3 author-token migration: read sessionID from the socket.io handshake's Cookie header in PadMessageHandler.handleClientReady, falling back to the legacy message-level field with a one-time deprecation warning per socket. Drop the client-side Cookies.get('sessionID') reads in pad.ts and timeslider.ts so the field is no longer sent by current clients. Existing integrators that set sessionID without HttpOnly keep working unchanged; the field on the message becomes optional and integrators should now mark the cookie HttpOnly; Secure; SameSite=Lax. Closes #7045 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(security): treat undecodable handshake cookies as absent (Qodo #7755) decodeURIComponent() throws URIError on malformed values like `%ZZ`. The unguarded call in PadMessageHandler.handleClientReady's readCookie() let a single bad cookie abort CLIENT_READY for that socket, allowing unauthenticated peers to spam server error logs and lock themselves out of pads. Catch URIError and treat the value as absent so the legacy message-level field still serves as a fallback. Other error classes still propagate. Add a backend test that asserts a `sessionID=%ZZ` cookie no longer aborts the handshake. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.7 KiB
6.7 KiB
Cookies
Cookies used by Etherpad.
| Name | Sample value | Domain | Path | Expires/max-age | Http-only | Secure | Usage description |
|---|---|---|---|---|---|---|---|
| express_sid | s%3A7yCNjRmTW8ylGQ53I2IhOwYF9... | example.org | / | Session | true | true | Session ID of the Express web framework. When Etherpad is behind a reverse proxy, and an administrator wants to use session stickiness, he may use this cookie. If you are behind a reverse proxy, please remember to set trustProxy: true in settings.json. Set in webaccess.js#L131. |
| language | en | example.org | / | Session | false | true | The language of the UI (e.g.: en-GB, it). Set by the pad client when the user changes My View → Language (currently in src/static/js/pad.ts, via setMyViewLanguage()). |
| prefs / prefsHttp | %7B%22epThemesExtTheme%22... | example.org | /p | year 3000 | false | true | Client-side preferences (e.g.: font family, chat always visible, show authorship colors, ...). Set in pad_cookie.js#L49. prefs is used if Etherpad is accessed over HTTPS, prefsHttp if accessed over HTTP. For more info see https://github.com/ether/etherpad-lite/issues/3179. |
| token | t.tFzkihhhBf4xKEpCK3PU | example.org | / | 60 days | true | true | A random token representing the author, of the form t.randomstring_of_length_20. Set by the server as an HttpOnly; SameSite=Lax cookie on the first GET to /p/:pad (see src/node/utils/ensureAuthorTokenCookie.ts). The server reads the cookie from the socket.io handshake in PadMessageHandler.handleClientReady to resolve the author. Not readable from browser JavaScript. See privacy.md. |
For more info, visit the related discussion at https://github.com/ether/etherpad-lite/issues/3563.
Etherpad HTTP API clients may make use (if they choose so) to send another cookie:
| Name | Sample value | Domain | Usage description |
|---|---|---|---|
| sessionID | s.1c70968b333b25476a2c7bdd0e0bed17 | example.org | Sessions can be created between a group and an author. This allows an author to access more than one group. The sessionID is set as a cookie by the integrator and is valid until a certain date. The session cookie can also contain multiple comma-separated sessionIDs, allowing a user to edit pads in different groups at the same time. Since #7045 Etherpad reads this cookie server-side from the socket.io handshake, so integrators should set it as HttpOnly; Secure; SameSite=Lax to mitigate XSS. More info - https://github.com/ether/etherpad-lite/blob/develop/doc/api/http_api.md#session |