I have a stylesheet with relatively specified background URLs (ie. "url(images/bg.png)"). When CSS aggregation is enabled, and I use the site over HTTPS, I sometimes get a warning about mixed mode content as a result of the CSS file containing an absolute URI with a scheme of 'HTTP' which was originally one of these relative links. I say this sometimes happens, because the stylesheet is sometimes generated with HTTPS links, other times with HTTP links.

My working theory is that the scheme embedded in the aggregated stylesheets is the same scheme in use at the time the stylesheet cache is generated. I've tested this theory as follows:

This triggers the problem:

  1. View the HTTP version of the website
  2. Log into the administration interface
  3. Go to the 'performance' page
  4. Clear the cache
  5. Switch to the HTTPS version of the website

Doing the above entirely on HTTPS doesn't trigger the problem.

The desired behaviour as I see it is that the scheme used in aggregated CSS when converting relative to absolute links (thus files on the same server) should mirror the scheme against which that CSS was requested.

Comments

Jeff.Parker created an issue. See original summary.

mfb’s picture

Version: 8.0.0-rc3 » 8.0.0
Priority: Normal » Major

This seems like a major bug, for sites that are on both HTTP and HTTPS (granted, it's more secure to be only on HTTPS, but not all sites are there yet). Drupal 7 CSS used URLs with a leading slash but Drupal 8 uses absolute URLs.

berdir’s picture

Status: Active » Needs review
StatusFileSize
new1.76 KB

Can you test the following patch? Will need to be injected and stuff, but should be enough to just confirm if this solves the problem.

berdir’s picture

Status: Needs review » Needs work

The last submitted patch, 3: cache-assets-by-scheme-2611420-3.patch, failed testing.

mfb’s picture

No that doesn't fix it - the CSS filename is still the same for HTTP and HTTPS. We need to save them to different filenames (or rewrite the URLs in the CSS to use leading-slash).

cilefen’s picture

What about configuring $settings['file_public_base_url'] in settings.php?

mfb’s picture

No that doesn't help. The URLs that are triggering the mixed content error are absolute URLs for shipped files in the aggregated CSS, like http://example.com/core/misc/feed.svg

cilefen’s picture

I think base_url used to be able to correct things like this but it is gone.

mfb’s picture

The problem is in CssOptimizer::rewriteFileURI() where file_create_url() is run on all URLs in aggregated CSS.

So, out-of-the-box, core is blindly slapping $GLOBALS['base_url'] on every URL in aggregated CSS. A contrib module could alter the file URLs, for example to use protocol-relative or root-relative URLs instead. In Drupal 7, sites that were accessible via different protocols worked out-of-the-box, but looks like a contrib module is now required to make this work by altering file URLs?

Arguably if core is going to put $GLOBALS['base_url'] in the CSS then it should generate a different aggregated CSS file for each base URL?

webchick’s picture

This got brought up in the context of #2606918: [securelogin] Secure Login so calling this a contrib project blocker.

berdir’s picture

StatusFileSize
new2.34 KB

Just pushing this along a bit, what about this? And yes, we might need the host and others in there too unless we do something like #1494670: References to CSS, JS, and similar files should be root-relative URLs: avoids mixed content warnings & fewer bytes to send. Maybe even then, considering that modules might alter URL's in there based on something.

David_Rothstein’s picture

See also #1961340: CSS aggregation breaks file URL rewriting because it abuses it where this problem was originally discussed (and which I think caused the issue in the first place) and #2375103: Regression: aggregated CSS should use server-relative URLs inside url() calls within the CSS file which was spun off a while ago to fix it.

Someone did suggest a fix like the patch above instead at one point though.

mfb’s picture

re: #13 this resolves the issue w/ HTTP and HTTPS base URLs in CSS in my testing. Javascript is still using the same file but that should be ok. Yes, I would say all caches (including aggregated files) using the base URL need to be keyed by the entire base URL.

wim leers’s picture

Issue tags: +HTTP/2

This will also affect HTTP/2 support.

wim leers’s picture

wim leers’s picture

Title: Aggregated CSS assumes HTTP, causes mixed content warning when accessed via HTTPS » [PP-1] Aggregated CSS assumes HTTP, causes mixed content warning when accessed via HTTPS
Status: Needs work » Postponed

#2375103: Regression: aggregated CSS should use server-relative URLs inside url() calls within the CSS file now has a patch with test coverage. If that lands, this issue is solved at the same time.

Postponing this issue for now, so that it can be re-tested after #2375103 lands. Hopefully we'll be able to just close this then.

wim leers’s picture

Title: [PP-1] Aggregated CSS assumes HTTP, causes mixed content warning when accessed via HTTPS » Aggregated CSS assumes HTTP, causes mixed content warning when accessed via HTTPS
Status: Postponed » Closed (duplicate)
Parent issue: » #1494670: References to CSS, JS, and similar files should be root-relative URLs: avoids mixed content warnings & fewer bytes to send
bsfajardo’s picture

Adding this comment here just in case it might be of help for someone.
If you are using Load Balancers or Reverse Proxies in front of your Drupal 8 website, make sure to add/uncomment the following lines in your settings.php file:

$settings['reverse_proxy'] = TRUE;
$settings['reverse_proxy_addresses'] = ['1.2.3.4', ...]; // List all the possible IPs for Reverse Proxies

In our scenario, we are using Varnish in front of Drupal, and the web server (Apache) is configured to serve only HTTP. That was causing the aggregated CSS to contain HTTP references to assets (fonts etc.). By turning these options on and rebuilding the cache, problem was fixed.

More details here: https://www.drupal.org/node/425990

Cheers!