[SOLVED] Mixed content issue on stylesheet

snathan99
Posts: 7
Joined: Thu May 10, 2018 2:22 pm

[SOLVED] Mixed content issue on stylesheet

Post by snathan99 »

I get mixed content warning on HTTPS

On viewing source I see the below href as http instead of HTTPS. So while I get the page content, the page theme is broken.

Code: Select all

<link rel="stylesheet" href="http://realclearagent.net/themes/black-2.0/css/style.css">
Was unable to find a setting that forced HTTPS on the URL.
User avatar
wiz
Posts: 749
Joined: Sat Oct 30, 2010 12:23 am

Re: Mixed content issue on stylesheet

Post by wiz »

Please answer a couple of questions so it'll be easier to help you.

1. What version of WonderCMS do you have?
2. What type of server do you have? (Apache, NGINX, IIS)
3. What version of PHP do you have?
4. How are you currently redirecting the rest of the website to HTTPS? Are you using the better security mode - or did you configure anything for the redirect to work?
5. Does the page work with any other theme correctly?

WonderCMS automatically turns the CSS paths to https if everything is configured correctly on your server.
Answer the above questions and we can slowly start solving the issue.
snathan99
Posts: 7
Joined: Thu May 10, 2018 2:22 pm

Re: Mixed content issue on stylesheet

Post by snathan99 »

1. What version of WonderCMS do you have?
WonderCMS 2.5.1
2. What type of server do you have? (Apache, NGINX, IIS)
NGINX reverse proxy server doing SSL offload to Apache Web Server
3. What version of PHP do you have?
PHP Version 7.0.28-0ubuntu0.16.04.1
4. How are you currently redirecting the rest of the website to HTTPS? Are you using the better security mode - or did you configure anything for the redirect to work?
I have NGINX configured to redirect all HTTP to HTTPS and this of course works.
5. Does the page work with any other theme correctly?
Same issue with other themes
WonderCMS automatically turns the CSS paths to https if everything is configured correctly on your server.
Can you point me to where in the code this happens to help navigate the issue?
Answer the above questions and we can slowly start solving the issue.
Hope that answers, thanks much.
User avatar
wiz
Posts: 749
Joined: Sat Oct 30, 2010 12:23 am

Re: Mixed content issue on stylesheet

Post by wiz »

Thanks for answering the questions. Since I don't have NGINX and can't test this, we'll need to communicate a bit for this issue to be solved.

A quick example of how HTTPS should work (on Apache):
https://wondercms.com/demo - if you look at the source code on the above demo, you will see the Apache server returns "HTTPS" everywhere and on all resources.

Your problem seems to be an NGINX issue, and some Googling turned out the following interesting result:
https://serverfault.com/questions/84741 ... esult-in-h
Could you try playing with the above and posting back?
I have NGINX configured to redirect all HTTP to HTTPS and this of course works.
The above is only partially true. While your NGINX configured server seems to redirect the user to HTTPS, but only AFTER they click a link.
Your NGINX server does not seem to be securing the CSS and JS resources. If you put your mouse over a link in your menu, you will see it's showing HTTP (and it redirects to HTTPS only AFTER clicking the link), which is also why the CSS doesn't load correctly and giving mixed content warnings

Can you point me to where in the code this happens to help navigate the issue?
Below is the WonderCMS function for generating HTTP and HTTPS URLs in index.php (starting at line 92)

Code: Select all

public static function url($location = '')
{
	return 'http' . (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '') . '://' . $_SERVER['SERVER_NAME'] . ((($_SERVER['SERVER_PORT'] == '80') || ($_SERVER['SERVER_PORT'] == '443')) ? '' : ':' . $_SERVER['SERVER_PORT']) . ((dirname($_SERVER['SCRIPT_NAME']) == '/') ? '' : dirname($_SERVER['SCRIPT_NAME'])) . '/' . $location;
}
The above code checks the server for HTTP and HTTPS and displays the proper links (but I don't think you should be fixing the function. Rather than that, try the above solution from the Google results).

I'm not an NGINX user, but will definitely try to help you out.
snathan99
Posts: 7
Joined: Thu May 10, 2018 2:22 pm

Re: Mixed content issue on stylesheet

Post by snathan99 »

You are statement that "I have NGINX configured to redirect all HTTP to HTTPS and this of course works is only partially true" got me thinking. Actually NGINX has nothing to do with delivering the HTTP url as opposed to HTTPS url. The server only sees HTTP. The offloading happens without any knowledge of the server. As far as Apache/WebServer is concerned this site is HTTP. Now the end user browser sees this site as HTTPS due to NGINX doing the magic. The http in the source is just "data" that flows through, for the BROWSER (not NGINX) to take action on. And the browser does not deliver HTTP because now this is mixed content.

We may need an override parameter as the determination of whether to delivery HTTP url or HTTPS url is currently dependent on where the webserver itself is delivering HTTP or HTTPS. Or I have to configure a HTTPS server on Apache and do a double encryption which defeats the purpose of having SSL configuration (including maintaining certificates, etc.) separated from Web server work.

Is there a way to formally request for an override parameter?
snathan99
Posts: 7
Joined: Thu May 10, 2018 2:22 pm

Re: Mixed content issue on stylesheet

Post by snathan99 »

On further research I noticed there is a $_SERVER['HTTP_FRONT_END_HTTPS'] that gets set to 'on' when using a HTTPS front-end proxy. So I modified the function as below:

Code: Select all

return 'http' . ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_FRONT_END_HTTPS']) && $_SERVER['HTTP_FRONT_END_HTTPS'] == 'on') ? 's' : '') . '://' . $_SERVER['SERVER_NAME'] . ((($_SERVER['SERVER_PORT'] == '80') || ($_SERVER['SERVER_PORT'] == '443')) ? '' : ':' . $_SERVER['SERVER_PORT']) . ((dirname($_SERVER['SCRIPT_NAME']) == '/') ? '' : dirname($_SERVER['SCRIPT_NAME'])) . '/' . $location;
For reference the original line was:

Code: Select all

return 'http' . (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '') . '://' . $_SERVER['SERVER_NAME'] . ((($_SERVER['SERVER_PORT'] == '80') || ($_SERVER['SERVER_PORT'] == '443')) ? '' : ':' . $_SERVER['SERVER_PORT']) . ((dirname($_SERVER['SCRIPT_NAME']) == '/') ? '' : dirname($_SERVER['SCRIPT_NAME'])) . '/' . $location;
This should automatically detect if there is a front-end server doing the SSL offloading and determine the correct protocol in the URLs automatically. Much better that hardcoding a parameter.
User avatar
wiz
Posts: 749
Joined: Sat Oct 30, 2010 12:23 am

Re: Mixed content issue on stylesheet

Post by wiz »

You are completely correct, thanks for elaborating and clearing it up (beautiful explanation btw).
Thank you also for providing a possible fix. Right now, I'm having trouble finding ANY documentation on

Code: Select all

$_SERVER['HTTP_FRONT_END_HTTPS']
with php.net

Is there any chance you know what version of PHP supports this or the origin of it? It's important to know, as we don't want to break users websites when pushing an update to their index.php file.

If this ends up in the next version of WonderCMS (2.5.2) (which I believe it should if there won't be any issues):
- your name and website will be added to the special contributors list -> https://wondercms.com/special-contributors
- your name and website in the new version release note - https://wondercms.com/whatsnew

Other than that, an excellent find and fix!
snathan99
Posts: 7
Joined: Thu May 10, 2018 2:22 pm

Re: Mixed content issue on stylesheet

Post by snathan99 »

When I explored my Apache/PHP server I noticed this was set to 'on' and assumed this appears automatically when using a front-end proxy. I realized now that I had forced that header from NGINX based on this SSL-Offloader NGINX blog. So it's actually a special header inserted by NGINX. I don't believe it would break anything as the code validates if this property is set before using it's value. It can also be an applicable property to add to the front end by others using a front-end SSL offloader. However, since it's a custom header nevertheless, I understand if you don't want to include this in your next release.

Appreciate you exploring the background on $_SERVER['HTTP_FRONT_END_HTTPS']. Should have checked it up myself before claiming this property is universal.

Thanks for creating and maintaining WonderCMS!
User avatar
wiz
Posts: 749
Joined: Sat Oct 30, 2010 12:23 am

Re: Mixed content issue on stylesheet

Post by wiz »

Thank you for using WonderCMS and contributing to it's development. This project would not be the same without users like yourself.

To continue this discussion just a bit further, kindly asking for your opinion:
Do you see any possible downsides to deploying this update to users servers? (user servers: Apache. NGINX, IIS - with PHP 5.5 and above)
snathan99
Posts: 7
Joined: Thu May 10, 2018 2:22 pm

Re: Mixed content issue on stylesheet

Post by snathan99 »

I did a little bit more research and it appears there are two parameters that are widely used to determine if the front-end is HTTPS. They are
  • HTTP_X_FORWARDED_PROTO
  • HTTP_FRONT_END_HTTPS
There are few who claim HTTP_X_FORWARDED_PROTO is the standard. I found this code snippet that suggests using both. My NGINX configuration sets both headers. Cisco ACE Load Balancer includes HTTP_X_FORWARDED_PROTO.

To answer your question, it appears to be a standard way of indicating to the downstream server information about the upstream protocol. I can't see the parameters being used for something other than it's indented purpose by anyone going forward. So my suggestion would be to include both and I don't foresee any issues with this update breaking existing installs.
Post Reply