From 1f825797f698540f1c2a3c593397c64ec25bbd49 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Thu, 17 Jul 2025 09:57:34 +0200 Subject: [PATCH] Allow trusted proxies to be provided via TRUSTED_PROXIES env var --- config/autoload/ip-address.global.php | 77 ++++++++++--------- module/Core/src/Config/EnvVars.php | 1 + ...eForwardedAddressesMiddlewareDecorator.php | 2 + 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/config/autoload/ip-address.global.php b/config/autoload/ip-address.global.php index 81a9f02f..1bac74c2 100644 --- a/config/autoload/ip-address.global.php +++ b/config/autoload/ip-address.global.php @@ -2,51 +2,56 @@ declare(strict_types=1); -use Psr\Container\ContainerInterface; use RKA\Middleware\IpAddress; use RKA\Middleware\Mezzio\IpAddressFactory; +use Shlinkio\Shlink\Core\Config\EnvVars; use Shlinkio\Shlink\Core\Middleware\ReverseForwardedAddressesMiddlewareDecorator; +use function Shlinkio\Shlink\Core\splitByComma; + use const Shlinkio\Shlink\IP_ADDRESS_REQUEST_ATTRIBUTE; -return [ +return (static function (): array { + $trustedProxies = EnvVars::TRUSTED_PROXIES->loadFromEnv(); - // Configuration for RKA\Middleware\IpAddress - 'rka' => [ - 'ip_address' => [ - 'attribute_name' => IP_ADDRESS_REQUEST_ATTRIBUTE, - 'check_proxy_headers' => true, - 'trusted_proxies' => [], - 'headers_to_inspect' => [ - 'CF-Connecting-IP', - 'X-Forwarded-For', - 'X-Forwarded', - 'Forwarded', - 'True-Client-IP', - 'X-Real-IP', - 'X-Cluster-Client-Ip', - 'Client-Ip', - ], - ], - ], + return [ - 'dependencies' => [ - 'factories' => [ - IpAddress::class => IpAddressFactory::class, - ], - 'delegators' => [ - // Make middleware decoration transparent to other parts of the code - IpAddress::class => [ - function ( - ContainerInterface $container, - string $name, - callable $callback - ): ReverseForwardedAddressesMiddlewareDecorator { - return new ReverseForwardedAddressesMiddlewareDecorator($callback()); - }, + // Configuration for RKA\Middleware\IpAddress + 'rka' => [ + 'ip_address' => [ + 'attribute_name' => IP_ADDRESS_REQUEST_ATTRIBUTE, + 'check_proxy_headers' => true, + 'trusted_proxies' => splitByComma($trustedProxies), + 'headers_to_inspect' => [ + 'CF-Connecting-IP', + 'X-Forwarded-For', + 'X-Forwarded', + 'Forwarded', + 'True-Client-IP', + 'X-Real-IP', + 'X-Cluster-Client-Ip', + 'Client-Ip', + ], ], ], - ], + 'dependencies' => [ + 'factories' => [ + IpAddress::class => IpAddressFactory::class, + ], + 'delegators' => [ + // Make middleware decoration transparent to other parts of the code + IpAddress::class => [ + fn ($c, $n, callable $callback) => + // If trusted proxies have been provided, use original middleware verbatim, otherwise decorate + // with workaround + $trustedProxies !== null + ? $callback() + : new ReverseForwardedAddressesMiddlewareDecorator($callback()), + ], + ], -]; + ], + + ]; +})(); diff --git a/module/Core/src/Config/EnvVars.php b/module/Core/src/Config/EnvVars.php index 4f57a721..072ee8db 100644 --- a/module/Core/src/Config/EnvVars.php +++ b/module/Core/src/Config/EnvVars.php @@ -89,6 +89,7 @@ enum EnvVars: string case CORS_ALLOW_ORIGIN = 'CORS_ALLOW_ORIGIN'; case CORS_ALLOW_CREDENTIALS = 'CORS_ALLOW_CREDENTIALS'; case CORS_MAX_AGE = 'CORS_MAX_AGE'; + case TRUSTED_PROXIES = 'TRUSTED_PROXIES'; /** @deprecated Use REDIRECT_EXTRA_PATH */ case REDIRECT_APPEND_EXTRA_PATH = 'REDIRECT_APPEND_EXTRA_PATH'; diff --git a/module/Core/src/Middleware/ReverseForwardedAddressesMiddlewareDecorator.php b/module/Core/src/Middleware/ReverseForwardedAddressesMiddlewareDecorator.php index 71d7545c..3a86b129 100644 --- a/module/Core/src/Middleware/ReverseForwardedAddressesMiddlewareDecorator.php +++ b/module/Core/src/Middleware/ReverseForwardedAddressesMiddlewareDecorator.php @@ -26,6 +26,8 @@ use function implode; * if trusted proxies are not set. * * @see https://github.com/akrabat/ip-address-middleware/pull/51 + * @deprecated Remove in future major version, and enforce users with multiple reverse proxies to provide the list via + * TRUSTED_PROXIES */ readonly class ReverseForwardedAddressesMiddlewareDecorator implements MiddlewareInterface {