|
1 | 1 | <?php |
2 | 2 |
|
| 3 | +declare(strict_types=1); |
| 4 | + |
3 | 5 | use Cake\Cache\Engine\FileEngine; |
4 | 6 | use Cake\Database\Connection; |
5 | 7 | use Cake\Database\Driver\Mysql; |
6 | 8 | use Cake\Log\Engine\FileLog; |
7 | 9 | use Cake\Mailer\Transport\MailTransport; |
8 | 10 | use function Cake\Core\env; |
9 | 11 |
|
| 12 | +$rateLimitCacheUrl = env('RATE_LIMIT_CACHE_URL', env('REDIS_URL')); |
| 13 | +$rateLimitEnabled = filter_var( |
| 14 | + env('RATE_LIMIT_ENABLED', $rateLimitCacheUrl !== null), |
| 15 | + FILTER_VALIDATE_BOOL, |
| 16 | +); |
| 17 | +$trustedProxyIps = array_values(array_filter(array_map( |
| 18 | + trim(...), |
| 19 | + explode(',', (string)env('TRUSTED_PROXY_IPS', '172.17.0.1')), |
| 20 | +))); |
| 21 | + |
10 | 22 | return [ |
11 | 23 | /* |
12 | 24 | * Debug Level: |
|
112 | 124 | ], |
113 | 125 | ], |
114 | 126 |
|
| 127 | + /* |
| 128 | + * Protection for the public package listing and autocomplete endpoints. |
| 129 | + * |
| 130 | + * RATE_LIMIT_CACHE_URL must be a redis:// DSN. The rate limiter remains |
| 131 | + * disabled until that shared, atomic cache has been configured. |
| 132 | + */ |
| 133 | + 'PublicRequestProtection' => [ |
| 134 | + 'rateLimitEnabled' => $rateLimitEnabled && is_string($rateLimitCacheUrl) && str_starts_with($rateLimitCacheUrl, 'redis://'), |
| 135 | + 'trustedProxyIps' => $trustedProxyIps, |
| 136 | + 'maxFilterValues' => max(1, (int)env('MAX_PACKAGE_FILTER_VALUES', 3)), |
| 137 | + 'rateLimits' => [ |
| 138 | + 'browse' => ['limit' => 90, 'window' => 60], |
| 139 | + 'filtered' => ['limit' => 15, 'window' => 60], |
| 140 | + 'autocomplete' => ['limit' => 30, 'window' => 60], |
| 141 | + ], |
| 142 | + ], |
| 143 | + |
115 | 144 | /* |
116 | 145 | * Configure the cache adapters. |
117 | 146 | */ |
|
122 | 151 | 'url' => env('CACHE_DEFAULT_URL'), |
123 | 152 | ], |
124 | 153 |
|
| 154 | + 'rate_limit' => [ |
| 155 | + 'className' => FileEngine::class, |
| 156 | + 'path' => CACHE . 'rate_limit' . DS, |
| 157 | + 'duration' => '+1 minute', |
| 158 | + 'prefix' => 'plugins_rate_limit_', |
| 159 | + 'fallback' => false, |
| 160 | + ] + ($rateLimitCacheUrl ? ['url' => $rateLimitCacheUrl] : []), |
| 161 | + |
125 | 162 | /* |
126 | 163 | * Configure the cache used for general framework caching. |
127 | 164 | * Translation cache files are stored with this configuration. |
|
0 commit comments