[6.x] Fix signed routes with expires
parameter
#38111
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What
This PR fixes a bug regarding signed route URLs allowing arbitrary expiration timestamps to be injected.
Why
When the URL is created with a parameter named
expires
, it will produce unexpected results that could be abused. This affects both temporary and non-temporary signed URLs, and routes with or without anexpires
parameter.How
For example, a temporary signed route that should expire after 30 minutes, will not fail if we pass an
expires
parameter with a timestamp 30 days in the future:This temporary signed URL uses the timestamp from the
parameters
instead of theexpiration
timestamp, so URL is considered valid even after 30 minutes have passed.Similarly, if we pass
'expires' => 0
, the URL will never expire because thesignatureHasNotExpired()
will treat theexpires
query parameter as empty and will not compare it to the current timestamp.Furthermore, when passing a non-empty array e.g.
'expires' => ['https://www.youtube.com/watch?v=dQw4w9WgXcQ']
, the URL will never be expired (arrays are always greater in comparison to numbers).Another example with a signed route that should not expire, will fail if we pass and
expires
parameter with a timestamp in the past:This signed URL uses the timestamp from the
parameters
in the query string, andsignatureHasNotExpired()
will treat it as non-empty and expired after 30 minutes.Changes details
The fix is similar to #30444: it will throw an exception when the
parameters
array contains a key namedexpires
.In the first commit I've only included a failing test that demonstrates the bug report, and the second commit includes the fix and more tests.