Commit d2ba257
committed
bug #58757 [RateLimiter] Fix DateInterval normalization (danydev)
This PR was merged into the 5.4 branch.
Discussion
----------
[RateLimiter] Fix DateInterval normalization
| Q | A
| ------------- | ---
| Branch? | 5.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Issues | n.a.
| License | MIT
This PR fixes a nasty bug (actually 2 different bugs) that caused our API to be unavailable for more than 24 hours. We needed to apply a manual mitigation to resolve the issue (see more below).
Specifically, the PR fixes a bug that causes the wrong calculation of the TTL keys containing the information of the rate limits for a `fixed window` limiter.
By doing so, our API consumers that respected the limit, actually were (wrongly) blocked by the RateLimiter, because the RateLimiter relies on the fact that the keys expire after the window defined by the configuration, so by using a wrong TTL, it ends up to a wrong evaluation of the consumed tokens.
To make it even worse, the TTL is reset at its original value every time a new rate limiter evaluation occurs for that key, so since our clients continued to do the requests (that without the bug would be accepted) the "denial of service" lasted indefinitely until we manually removed all the affected keys in Redis.
**Bug 1**
Prerequisites:
- Using as global php timezone one that has DST (in our case `Europe/Rome`)
- Executing code within one hour from the switch CEST->CET or in other words between `27 October 2024 2:00AM CEST` and `27 October 2024 2:59AM CEST` (e.g. `27 October 2024 2:02AM CEST`)
- Using a fixed window rate limiter
- Doing the 1st request for a given key (so that the TTL is calculated and set)
- Using PHP >= 8.1 (read more in the next comment)
**Bug 2**
Prerequisites:
- Using as global php timezone one that has DST (in our case `Europe/Rome`)
- Executing code in a CEST time where by adding the rate limiter interval the time goes to CEST, (e.g. `27 October 2024 2:50AM CEST` using an rate limiter interval of 20 minutes)
- Using a fixed window rate limiter
- Doing the 1st request for a given key (so that the TTL is calculated and set)
- Using PHP >= 8.3 (read more in the next comment)
Those bugs are caused by a php behaviour that it's not optimal nor intuitive, I feel like **Bug 1** could be defined as a PHP bug, while **Bug 2** is intended behaviour, anyway it's like this, and we need to deal with it at the application level.
Commits
-------
d81af98 [RateLimiter] Fix DateInterval normalizationFile tree
3 files changed
+40
-2
lines changed- src/Symfony/Component/RateLimiter
- Tests
- Util
3 files changed
+40
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
72 | | - | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
73 | 77 | | |
74 | 78 | | |
75 | 79 | | |
| |||
Lines changed: 34 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
76 | 77 | | |
77 | 78 | | |
78 | 79 | | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
79 | 113 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| |||
0 commit comments