3

I am currently having issues with the following

Mixed Content: The page at 'https://www.example.com/' was loaded over HTTPS, but requested an insecure stylesheet

This is a Wordpress website on a Centos server with httpd installed.

I have following virtual host setup in `http.conf:

NameVirtualHost *:80
NameVirtualHost *:443


<VirtualHost *:443>
    DocumentRoot /var/www/html/example
    ServerName www.example.com
    ServerAlias example.com
    SSLEngine on
    SSLCACertificateFile /etc/httpd/conf/ssl.crt/intermediate.crt
    SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt
    SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key
</VirtualHost>

<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias example.com
    Redirect / https://www.example.com/
</VirtualHost>

In my httpd.conf I have changed AllowOverride to all, so it looks like so:

<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

I can confirm the htaccess is working as I am using iTheme security plugin and this is working as expected, also if I type some garbage in the htacces I get a server misconfiguration error as expected.

I have changed both the Wordpress URLs in the Dashboard to use https instead of http.

Once all of this was done, I was able to access the site over HTTP, be redirected to the HTTPS version of the site and see the site. However in the console I receive the error regarding mixed content and the padlock shield appears as yellow or red crossed as opposed to the desired green.

There are a few files that are an issue and I know for example I can change the URLs manually to use https as opposed to http. As I understand it, I can use change the URL to the below and this will simply adjust the link to the current protocol in use:

<img src="//www.example.com/image.jpg" />

I have also seen that if a resource is not available over https I can simply do the following:

https://example.com/imageserver?url=http://otherdomain.com/someimage.jpg&hash=abcdeafad

I am however, trying to find a way to fix all of these in one go using htaccess (something I am sure I have done before, but my snippets aren't working for me).

There are two main snippets I have used in an attempt to force everything over https, the first being:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On

#These Lines to force HTTPS
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]

RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

The second is from Dave Walsh:

RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]

However, neither seem to solve my issue. As a precaution I have restarted the httpd service after every change even htaccess changes which shouldn't require a restart, however the situation remains the same. Can anyone point me in the right direction?

3
  • Change RewriteRule ^/(.*) to RewriteRule ^(.*) if this is in your htaccess file.
    – hjpotter92
    Sep 18, 2015 at 11:10
  • @hjpotter92 Many thanks for the response, I have change the lines to the following #These Lines to force HTTPS RewriteCond %{SERVER_PORT} !^443$ RewriteRule ^(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L] Unfortunately it still won't play nice. Sep 18, 2015 at 11:18
  • If it helps at all, you can track down mixed content issues quickly with this Desktop app, or request a report from them: ecommerce.co.uk/httpschecker
    – stilliard
    Mar 29, 2016 at 15:26

1 Answer 1

6

The simplest solution is to replace all links manually using this solution below will save your time and its very straight forward.

The idea is to remove all (protocol HTTP and HTTPS) and leave them to use protocol relative URL https://stackoverflow.com/a/15146073/3599237

We can do this using the following code for index.php

<?php
//this lined added here
ob_start();
/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );

//and these lines also 
$output = ob_get_contents();
ob_end_clean();

$output = str_replace(array("https://", "http://"), "//", $output);
echo str_replace('http:\/\/', "\/\/", $output);

Update: You can simply use Content Security Policy

The HTTP Content-Security-Policy (CSP) upgrade-insecure-requests directive instructs user agents to treat all of a site's insecure URLs (those served over HTTP) as though they have been replaced with secure URLs (those served over HTTPS). This directive is intended for web sites with large numbers of insecure legacy URLs that need to be rewritten.

The upgrade-insecure-requests directive is evaluated before block-all-mixed-content and if it is set, the latter is effectively a no-op. It is recommended to set either directive, but not both, unless you want to force HTTPS on older browsers that do not force it after a redirect to HTTP.

Put below line into header section (header.php file).

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

For more information please read: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests

7
  • 2
    using // instead of the protocol is definitely the way to go. Haven't seen a solution like this though, very interesting. Jun 20, 2016 at 8:30
  • @TheHumbleRat: I have also solved this issue when using Wordpress Super Cash plugin, if you used it please notify I will share with you the solution.
    – Akam
    Jun 21, 2016 at 20:22
  • Working solution, but not perfect. If website contains for example links to other websites that script will change them to https also.
    – electroid
    Aug 30, 2016 at 10:26
  • @electroid: you can work on it to replace your domain only.
    – Akam
    Aug 30, 2016 at 11:54
  • @Akam is there a way to do the same to domain.com/wp-admin/* ? tried to edit /wp-admin/index.php with the same trick, but no luck at all
    – balexandre
    Mar 23, 2018 at 16:05

Not the answer you're looking for? Browse other questions tagged or ask your own question.