Use forwarded protocol if a proxy is used

Created on 23 April 2020, over 4 years ago
Updated 29 August 2024, 5 months ago

On some projects with complex hosting setups Drupal can think the consumer route is HTTP even though it is HTTPS.

For anyone struggling with this issue this patch enforces HTTPS when getting the consumer route.

A patch for Onelogin PHP SAML is also attached which changes the start of the URL from http:// to https:// when checking if the current page is the consumer route.

๐Ÿ› Bug report
Status

Fixed

Version

4.0

Component

Code

Created by

๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom robert castelo

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Merge request !27Issue #3130317: Enforce HTTPS โ†’ (Merged) created by matthijs
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States jproctor

    This looks like it should work, but Iโ€™m having a hard time testing it and I want to be sure I understand:

    Given:

    1. Reverse proxy server โ€œwww.example.comโ€
      • Has (for this example) IP address 10.1.2.3
      • Forwards all requests to http://drupal.example.com
      • Correctly sets HTTP_X_FORWARDED_PROTO to https when handing a secure request
    2. Drupal server โ€œdrupal.example.comโ€
      • $settings['reverse_proxy'] = TRUE;
      • $settings['reverse_proxy_addresses'] = ['10.1.2.3']

    When a request comes in to https://www.example.com/saml/drupal_login/example_idp, it forwards the request to http://drupal.example.com/saml/drupal_login/example_idp.

    Without this patch, the <AuthnRequest> goes out with http://... in the useful URLs, but with this patch, it should be https://..., yes?

    To test this, I enabled debugging on /admin/config/people/saml_sp and tried

    curl -H "HTTP_X_FORWARDED_PROTO: https" http://drupal.example.com

    I get the same output regardless of whether I have the patch in place:

    [assertionConsumerService] => Array
        (
            [url] => http://d9.lndo.site/saml/consume
            [binding] => urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
         )
    

    Itโ€™s possible that my test environment โ€” Iโ€™m doing everything on one machine and Drupal is running in a container โ€” is not a sufficient way to test this because Docker or Trรฆfik or something is getting in the way.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States jproctor

    Update: I guess I needed to stop staring at it for a little while.

    Yes, Trรฆfik was in the way, but I was able to get around it (and also specify the header correctly because ugh PHP), and now it seems to work regardless of whether I have the patch:

    curl -H "X-FORWARDED-PROTO: https" http://localhost:57961/saml/drupal_login/example_idp

    [assertionConsumerService] => Array
        (
            [url] => https://localhost:57961/saml/consume
            [binding] => urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
         )
    
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium matthijs

    I think your verifying the behavior at the wrong place. The problem is that \OneLogin\Saml2\Utils::getSelfURLhost() will return an http URL because it doesn't detect https unless you instruct it to read the forwarded headers.

    Also while testing don't forget to set the X-Forwarded-For header as well.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States jproctor

    Right, but we care about that because it generates the ACS URL in the <AuthnRequest>. Is there a post-login validation step that fails if OneLogin has the wrong URL (http) even if the right one (https) goes out to the IdP?

    I do have one other question: do we need a service for this, or could we do it in the controllers where we initiate and consume the exchange with the IdP?

  • First commit to issue fork.
  • Status changed to RTBC 6 months ago
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom very_random_man

    Can confirm that MR27 fixes this for me. I've got D10 running in an auto-scaling group on AWS behind an Elastic Load Balancer.

    The complete fix for me was to add `X-FORWARDED-PROTO` header with the value `https` to the nginx config serving drupal and to also ensure that this is in settings.php:

    $settings['reverse_proxy'] = TRUE;
    $settings['reverse_proxy_addresses'] = ['my.ELB.hostname.here']
    

    The last line with the addresses isn't required for this fix btw as the MR only passes the first setting to the SAML library and that combines with the header to trigger the logic. For reference, this is the code that decides on what protocol to use: https://github.com/SAML-Toolkits/php-saml/blob/cadabb78de2590e82fbacbb01...

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States jrglasgow Idaho

    The attached patch or the Onelogin SAML library doesn't look like it is checking for a proxy or any settings to indicate it is behind a proxy. If that patch is required then I would suggest updating it to check so it doesn't somehow break something else... otherwise the patch should be added to the saml_sp composer.json so it will get automatically applied upon composer install.
    Ideally the patch, if required, should be added to an issue file on the onelogin SAML library project.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom very_random_man

    I think the patches in #1 should be ignored. The MR definitely feels like the correct approach as it basically facilitates the OneLogin SAML library to work as designed.

  • Pipeline finished with Skipped
    5 months ago
    #254483
  • Status changed to Fixed 5 months ago
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States jrglasgow Idaho

    I am merging.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024