Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP redirection in midst of a HTTPS context #4129

Open
otyugh opened this issue Jan 1, 2024 · 6 comments
Open

HTTP redirection in midst of a HTTPS context #4129

otyugh opened this issue Jan 1, 2024 · 6 comments

Comments

@otyugh
Copy link

otyugh commented Jan 1, 2024

How to reproduce : set your firefox browser with dom.security.https_only_mode=true

As a result you'll get stopped : 1/after login 2/after editing a page or settings or enabling a mod with the error "NS_ERROR_REDIRECT_LOOP".

If you check that line you can see that, yes. A http request is made - even out of a HTTPS context.

file-R959e46f7706bbe4968f796cd3b217b62

@xrat
Copy link

xrat commented Jan 1, 2024

I cannot reproduce this, neither on one of my own wikis nor https://www.dokuwiki.org/ . Login and editing work with HTTPS only.

@otyugh
Copy link
Author

otyugh commented Jan 1, 2024

(note : The problem only occurred on successful logins)

Could it be a combination of my nginx settings & dokuwiki ?

I can give you a "default dokuwiki" that I'd just pasted on my webserver if it can help pinpoint the issue (maybe not, I'm still trying to cope with the fact you couldn't reproduce it :<)
https://t2.arzinfo.eu.org/doku.php?id=start

@xrat
Copy link

xrat commented Jan 1, 2024

I can reproduce your error on your https://t2.arzinfo.eu.org/doku.php?id=start
I doubt that this is a bug in DW. Also, I'd rather not suspect nginx.

Does your setup involve a proxy? What's your DW baseurl setting?
But even then I wonder whether something else is going on since the error is a redirection loop. Also, your server even sends a Strict-Transport-Security: max-age=31536000; includeSubdomains; preload header for each request, so my understanding is that a browser should not even try to access http://….

@otyugh
Copy link
Author

otyugh commented Jan 1, 2024

my understanding is that a browser should not even try to access http://…

Yes, at least, that's what I was trying to go for.

Does your setup involve a proxy?

No proxy.

What's your DW baseurl setting?

I defined no baseurl - but I just tried to set it up, and it seem to fix the problem when set.

Now, I still believe it's a bit of an issue in the basurl guessing but as nobody beside me seem to be able to replicate it, it looks very niche.

For "if anyone fall on the same thing and do some connection I don't" here's an extract of my nginx config

add_header Content-Security-Policy "default-src 'none'; base-uri 'self'; script-src 'self'; img-src 'self' data:; style-src 'self'; form-act>
add_header X-XSS-Protection "1; mode=block";
add_header Feature-Policy "geolocation none;midi none;notifications none;push none;sync-xhr none;microphone none;camera none;magnetometer no>

map $sent_http_content_type $expires {
        default                    off;
        text/html                  epoch;
        text/css                   14d;
        application/javascript     off;
        ~image/                    max;
}

server {
        listen 443 ssl http2;
        server_name xxx.xxx;

##SSL
        ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305';
        ssl_ecdh_curve secp384r1;
        ssl_session_cache builtin:1000 shared:SSL:10m;
        ssl_session_timeout 1d;
        ssl_session_tickets off;
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always;
        add_header X-Frame-Options deny;
        add_header X-Content-Type-Options nosniff;
        add_header Content-Security-Policy "default-src 'self'; base-uri 'self'; script-src 'self' 'unsafe-inline'; img-src 'self' data:; style-src >
        add_header X-XSS-Protection "1; mode=block";
        add_header Referrer-Policy "no-referrer";
        #add_header Feature-Policy "geolocation none;midi none;notifications none;push none;sync-xhr none;microphone none;camera none;magnetometer n>
        #add_header Permission-Policy "geolocation=(none),midi=(none),notifications=(none),push=(none),sync-xhr=(none),microphone=(none),camera=(non>
        add_header Permissions-Policy "geolocation=(self), microphone=()";
        
##php
        location ~ \.php {
                fastcgi_split_path_info ^(.+?\.php)(/.*)$;
                if (!-f $document_root$fastcgi_script_name) {
                        return 404;
                }
                # A handy function that became available in 0.7.31 that breaks down 
                # The path information based on the provided regex expression
                # This is handy for requests such as file.php/some/paths/here/ 
        
                fastcgi_param  PATH_INFO          $fastcgi_path_info;
                fastcgi_param  PATH_TRANSLATED    $document_root$fastcgi_path_info;
        
                fastcgi_param  QUERY_STRING       $query_string;
                fastcgi_param  REQUEST_METHOD     $request_method;
                fastcgi_param  CONTENT_TYPE       $content_type;
                fastcgi_param  CONTENT_LENGTH     $content_length;
        
                fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
                fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
                fastcgi_param  REQUEST_URI        $request_uri;
                fastcgi_param  DOCUMENT_URI       $document_uri;
                fastcgi_param  DOCUMENT_ROOT      $document_root;
                fastcgi_param  SERVER_PROTOCOL    $server_protocol;
        
                fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
                fastcgi_param  SERVER_SOFTWARE    nginx;
        
                fastcgi_param  REMOTE_ADDR        $remote_addr;
                fastcgi_param  REMOTE_PORT        $remote_port;
                fastcgi_param  SERVER_ADDR        $server_addr;
                fastcgi_param  SERVER_PORT        $server_port;
                fastcgi_param  SERVER_NAME        $server_name;
        
                fastcgi_pass   unix:/var/run/php/php7.4-fpm.sock;
                fastcgi_index  index.php;
        }
        include snippets/ssl_credentials.conf;
        client_max_body_size 42M;
        root /srv/$subdomain;
        index index.html index.php;
        location / {
                try_files $uri $uri/ =404;
        }
}

@splitbrain
Copy link
Collaborator

It seems the HTTPS environment variable isn't set. Which is curious. I guess we could also check for the protocol in the REQUEST_URI...

dokuwiki/inc/init.php

Lines 535 to 547 in 5719588

function is_ssl()
{
// check if we are behind a reverse proxy
if (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') == 'https') {
return true;
}
if (preg_match('/^(|off|false|disabled)$/i', $_SERVER['HTTPS'] ?? 'off')) {
return false;
}
return true;
}

@otyugh
Copy link
Author

otyugh commented Jan 2, 2024

Oh nice.
Looking at understanding the behavior better I tried to add some echo '<pre>'.print_r($_SERVER,true).'</pre>'; to the function.

Apparently the "is_ssl" is called 3 time on each page. The 3 $_SERVER output are exactly the same (I used diff to check).

Also neither
-HTTP_X_FORWARDED_PROTO
-HTTPS

Are ever set (I'm confused too ! Everything works https without any https flag ?)

Here is also the $SERVER difference between "normal POST request" and the after "pushing the send button while editing a dokuwiki" is this :

-    [REQUEST_METHOD] => POST
+    [REQUEST_METHOD] => GET

-    [REMOTE_PORT] => 40084
+    [REMOTE_PORT] => 10426

-    [CONTENT_LENGTH] => 187
+    [CONTENT_LENGTH] => 

-    [CONTENT_TYPE] => application/x-www-form-urlencoded
+    [CONTENT_TYPE] => 

-    [HTTP_SEC_FETCH_USER] => ?1
-    [HTTP_ORIGIN] => null
-    [HTTP_CONTENT_LENGTH] => 187
-    [HTTP_CONTENT_TYPE] => application/x-www-form-urlencoded

Also because nothing changes for is_ssl check, that condition is the one that triggers every time and return "false"

 if (preg_match('/^(|off|false|disabled)$/i', $_SERVER['HTTPS'] ?? 'off')) { 
         return false; 
  } 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants