Repository navigation
Conversation
michalsn
left a comment
There was a problem hiding this comment.
I'm strongly against merging this in its current form. In the normal framework flow, the session cookie and IP address are validated before reaching these queries. What actual bug or exploitable path does this fix?
Switching from simpleQuery() to query() and changing the lock state representation introduce behavioral changes beyond escaping. Without a demonstrated problem, I don’t think that additional scope is justified.
4d85b99 to
7b00e71
Compare
7b00e71 to
3607a57
Compare
paulbalandan
left a comment
There was a problem hiding this comment.
Please clarify the description and changelog as defensive escaping unless there is a demonstrated path for these values to reach the handler through normal session handling. The tests inject an invalid session ID and IP address directly; they do not establish an exploitable framework path.
3607a57 to
1a4a6db
Compare
|
Thanks @paulbalandan and @michalsn for the feedback! I agree with your assessment: in the standard framework HTTP lifecycle with stock To directly address the question of what actual issue this fixes, I have updated the PR description and changelog to frame this change purely as defensive escaping / hardening:
|
paulbalandan
left a comment
There was a problem hiding this comment.
Please update the PR description too. It still says the queries use bindings, but the implementation uses escape() with simpleQuery(), which also preserves the existing DBQuery event behavior.
| - **Images:** Fixed a bug in `ImageMagickHandler::save()` where saving without an extension or with an unsupported extension threw an `ImagickException` instead of falling back to the image's format. | ||
| - **Security:** Fixed a bug where `Security::__construct()` threw a `TypeError` when the CSRF cookie was an array, causing an HTTP 500 response for affected requests. | ||
| - **Session:** Fixed a bug where `BaseHandler::destroyCookie()` did not send the `SameSite` attribute in the `Set-Cookie` header, which could prevent browsers from properly clearing the session cookie. | ||
| - **Session:** `PostgreHandler::lockSession()` and `releaseLock()` now defensively escape session IDs and IP addresses using `BaseConnection::escape()`. |
There was a problem hiding this comment.
Please move it into the "Changes" section.
| - **Session:** `PostgreHandler::lockSession()` and `releaseLock()` now defensively escape session IDs and IP addresses using `BaseConnection::escape()`. | |
| - **Session:** Added defensive escaping of session lock arguments in `PostgreHandler`, preserving the existing locking behavior. |
The entry describes defensive escaping, not a fixed bug, so it belongs in the Changes section, as requested in review.
Description
PostgreHandler::lockSession()andreleaseLock()interpolated the session ID and the IP address directly into the advisory lock SQL. They now escape both values with$this->db->escape()before the statement is built, and still send it throughsimpleQuery().This is defensive escaping; it is not a fix for a demonstrated exploitable path. In the stock framework flow,
Sessionvalidates the session ID against$sidRegexpandRequestTraitvalidates the IP address withfilter_var(..., FILTER_VALIDATE_IP), so neither value can break out of the string literal today.What the change does address:
PostgreHandleris the only database session handler that interpolates its lock arguments.MySQLiHandlerhashes the argument withmd5()first, which yields a clean hex string, whilepg_advisory_lock()needs an integer, so PostgreSQL'shashtext()is applied to the raw value.simpleQuery()is kept on purpose:query()would emitDBQueryevents into the Debug Toolbar while the session lock is acquired and released, and the tests assert that noDBQueryevent fires. The value stored in$this->lock, the lock lifecycle, and the return types are unchanged.Checklist: