1

If I go to https://example.com, then everything is working fine. However if I go to https://www.example.com, then none of my static files load because it says that it goes against the CSP. Thus, I'm trying to redirect all www requests to non-www.

Here is my .htaccess code:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^$ public/ [L]
    RewriteRule (.*) public/$1 [L]

    RewriteCond %{HTTPS} off 
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

</IfModule>

<IfModule mod_headers.c>
    Header set Content-Security-Policy: "default-src 'self'; font-src https://fonts.gstatic.com; style-src 'self' https://fonts.googleapis.com; img-src 'self'; child-src 'none';"
...
</IfModule>
MrWhite
  • 43,179
  • 8
  • 60
  • 84
jag6
  • 35
  • 8

3 Answers3

1
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^$ public/ [L]
    RewriteRule (.*) public/$1 [L]

    RewriteCond %{HTTPS} off 
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

</IfModule>

Your rules are in the wrong order (and incorrect). The canonical redirects need to go before the internal rewrites to the /public subdirectory (where I assume you have another .htaccess file). As written, they are not doing anything. But also, your redirect to supposedly remove the www prefix is not doing that, but instead redirecting to the same host, which would have resulted in a redirect loop.

Your rules should be written like this instead:

RewriteEngine On

# Redirect www to non-www (and HTTPS)
RewriteCond %{HTTP_HOST} ^www\.(.+?)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]

# Redirect HTTP to HTTPS (already non-www)
RewriteCond %{HTTPS} off 
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# Rewrite everything to the "public" subdirectory
RewriteRule (.*) public/$1 [L]

No need for the <IfModule> wrapper and the first rule (ie. RewriteRule ^$ public/) is redundant since this would be handled by the second rule anyway.

By redirecting from www to non-www (and HTTPS) first we minimise the number of canonical redirects to at most one. But this does assume you are not intending to implement HSTS.

if I go to https://www.example.com, then none of my static files load because it says that it goes against the CSP.

Probably because you are referencing your "static files" using absolute URLs of the form https://example.com/..., not www.example.com.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
  • "By redirecting from www to non-www (and HTTPS) first we minimise the number of canonical redirects to at most one. But this does assume you are not intending to implement HSTS." I did implement HSTS with "Header set Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload" env=HTTPS". with the includeSubDomains, everything should be ok, right? – jag6 Mar 10 '23 at 20:11
  • 1
    @jag6 If you are implementing HSTS then you will need to redirect from HTTP to HTTPS on the _same host_ first. ie. you cannot redirect from www to non-www first. You need to reverse the first two rules. This means that a request for `http://www.example.com/` will encounter two redirects instead of one. However, that `Header` directive by itself does not implement HSTS. See [my answer](https://webmasters.stackexchange.com/a/131970/1243) to the following question on the Webmasters stack: https://webmasters.stackexchange.com/questions/115125/hsts-implementation-when-using-www-tld – MrWhite Mar 10 '23 at 23:04
0

One of the best ways to solve this is to create a ServerAlias in your virtual host configuration in apache/httpd.

ServerName example.com
ServerAlias www.example.com

That will solve it and also some users still thinks that www is required to visit a site.

Vidal
  • 2,605
  • 2
  • 16
  • 32
0

I believe that the files which are static are not hosted on the same domain (www.example.com vs example.com), they may be blocked by the CSP. To resolve this issue, one way might be is to your CSP so that the static files can loaded from the exact and correct location. To your guidance see this. To fix this, you can update your CSP to allow the static files to be loaded from the correct domain.

Header set Content-Security-Policy: "default-src 'self'; font-src https://fonts.gstatic.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' https://exampele.com; child-src 'none';"

Now the images will be loaded from example.com and from the self domain as well. Additionally, you might also need to adjust the policy on where the files are hosted and accesssed.