🌐 AI搜索 & 代理 主页
Skip to content

[Security] HttpUtils::createRequest ignores X-Forwarded-* headers #61560

@kira0269

Description

@kira0269

Symfony version(s) affected

7.3.1

Description

In my project, I'm currently using the HWIOAuthBundle bundle in order to implement sign in via google.

The redirect uri configured in Google console needs to be http(s)://localhost/.... or a domain with a valid suffix like .com or .io. Using Traefik, I usually configure my projects with domains like app1.docker.localhost, but Google doesn't allow it, so I switched and now I try to use path prefix reverse proxying like http://localhost/app1.

I configured Traefik to add the needed X-Forwarded-* headers and configured my Symfony app after the documentation so it works properly.

In the other hand, the HWIOAuthBundle uses Symfony\Component\Security\Http\HttpUtils in order to create redirect uri and to process OAuth workflow. The OAuthAuthenticator from the bundle contains the lines below:

public function authenticate(Request $request): Passport
{
         // $checkPath can be either a path, or a route name
        [$resourceOwner, $checkPath] = $this->resourceOwnerMap->getResourceOwnerByRequest($request);
        
        //...
       
        $accessToken = $resourceOwner->getAccessToken(
            $request,
            $this->httpUtils->createRequest($request, $checkPath)->getUri()
        );

       //...
}

And there is the bug. With the following context:

  • Traefik redirects http://localhost/my-app to my symfony app
  • /my-app is configured as X-Forwarded-Prefix

We have the following results:

  • $request->getUri() => http://localhost/my-app/
  • $this->httpUtils->createRequest($request, '/')->getUri() => http://localhost/my-app/my-app/

After digging, the main difference I found is that the REQUEST_URI attribute from the request's server bag has changed from / to /my-app/ between the initial $request object and the one created by $this->httpUtils->createRequest($request, '/')

In addition, this also impacts every authenticator using HttpUtils::createRequest(), like the FormLoginAuthenticator when theuse_forward option is enabled.

How to reproduce

Configure a local reverse proxy like Traefik.
With docker compose:

services:
  my-app:
    #...
    environment:
      SYMFONY_TRUSTED_PROXIES: "PRIVATE_SUBNETS"
      SYMFONY_TRUSTED_HEADERS: "x-forwarded-for,x-forwarded-host,x-forwarded-proto,x-forwarded-port,x-forwarded-prefix"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.my-app.rule=PathPrefix(`/my-app`)"
      - "traefik.http.routers.my-app.entrypoints=web"
      - "traefik.http.middlewares.app-stripprefix.stripprefix.prefixes=/my-app"
      - "traefik.http.routers.my-app.middlewares=app-stripprefix"

Create a simple controller and generate the uris:

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\HttpUtils;

class IndexController extends AbstractController
{
    #[Route('/')]
    public function test(Request $request, HttpUtils $httpUtils)
    {
        $uri = $request->getUri();

        $newRequest = $httpUtils->createRequest($request, '/');
        $newUri = $newRequest->getUri();

        dd($uri, $newUri);
    }

Possible Solution

No response

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions