Forum Moderators: phranque

Message Too Old, No Replies

Strict-Transport-Security for all but HTML page

         

smallcompany

10:26 pm on Nov 28, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



So I tried implementing Strict-Transport-Security for a site. Testing returned Error: No HSTS header.

I looked into it, but found it tough to find anything that would point me to a solution. Then, as I was looking into headers, I saw that files like CSS or JS except the actual html page and images showed the Strict-Transport-Security as per the instruction from .htaccess.

Why would this be? What prevents HTML page to have this as well?

Thank you

not2easy

12:42 am on Nov 29, 2018 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Are all the files in one single directory or are they in various folders? Rewrite is not always inherited in subfolders.

smallcompany

1:09 am on Nov 29, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The requested pages I tested are in the root, and files like CSS or JS are in subfolders. .htaccess is in the root as well.

not2easy

4:04 am on Nov 29, 2018 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Do the html pages have http: links on the pages?

lucy24

4:48 am on Nov 29, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



What is the actual command that is intended to set the header? You say “instruction from htaccess” but that doesn’t give the information we need. Is it a Header Set directive?

not2easy, I don’t think this is a mod_rewrite command, so inheritance fortunately is not an issue.

smallcompany

8:52 pm on Dec 2, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The command:

Header set Strict-Transport-Security "max-age=300; includeSubDomains; preload" env=HTTPS

300 is for testing purpose, I also tried using "always" with no change.

In addition, the hosting provider was 302ing the non-HTTPS versions, and that has been resolved now.

Testing for HSTS on hstspreload.org now returns:

Error: No HSTS header

and also

Error: HTTP does not redirect to HTTPS
`http://example.com` (HTTP) redirects to `https://www.example.com/`. The first redirect from `http://example.com` should be to a secure page on the same host (`https://example.com`).

This is the first time I face such requirement. I've always thought, the less number of redirects, the better. Is this as simple as HTTP 301 to HTTPS, then 301 to WWW?

When I installed SSL certificate for the first time, I added this to .htaccess:

RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://www.example.com/$1 [R=301,L]


I also have this, from years ago, made by jdMorgan:

#URL CANONICALIZATION OF ALL NON-WWW DOMAIN VARIANTS
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([a-z0-9][a-z0-9\-]*[a-z0-9]\.(co\.[a-z]{2}|[a-z]{2,6}))\.?(:[0-9]{1,5})?$ [NC]
RewriteRule (.*) https://www.%1/$1 [R=301,L]
#
#URL CANONICALIZATION OF ALL WWW DOMAIN VARIANTS
RewriteCond %{HTTP_HOST} ^www\.([a-z0-9][a-z0-9\-]*[a-z0-9]\.(co\.[a-z]{2}|[a-z]{2,6}))(\.|\.?:[0-9]{1,5})$ [NC]
RewriteRule (.*) https://www.%1/$1 [R=301,L]


Finally, I see that for HSTS, the requirement is clear:

Serve an HSTS header on the base domain for HTTPS requests:

- The max-age must be at least 31536000 seconds (1 year).
- The includeSubDomains directive must be specified.
- The preload directive must be specified.
- If you are serving an additional redirect from your HTTPS site, that redirect must still have the HSTS header (rather than the page it redirects to).

and I now wonder how my current settings fit into this.

Thank you

not2easy

10:32 pm on Dec 2, 2018 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Error: HTTP does not redirect to HTTPS
`http://example.com` (HTTP) redirects to `https://www.example.com/`. The first redirect from `http://example.com` should be to a secure page on the same host (`https://example.com`)

I'm no help for the hsts issue, but one single rewrite rule should handle both http: and www rewrites. Putting them in separate rules may be giving you the error you posted if the rules are not in the correct order.

Using
#Redirect invalid and non www requests
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
handles both non-www and non https requests. This rule needs to come after all other rewrite rules.

The Rules shared from JDMorgan appear to be for some specific application, those are not the general format for management of www/non-www and/or http/https rules.

All this assumes some details that are not shared in this thread: You are hosted on an Apache server and also have a method to control indexes.

lucy24

12:06 am on Dec 3, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Testing for HSTS on hstspreload.org now returns:
Error: HTTP does not redirect to HTTPS
`http://example.com` (HTTP) redirects to `https://www.example.com/`. The first redirect from `http://example.com` should be to a secure page on the same host (`https://example.com`)
You are right and the utility is wrong, so maybe you should find a different place to do your testing.

When I installed SSL certificate for the first time, I added this to .htaccess:

RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
Did you not already have a domain-name-canonicalization redirect? It should be a single rule, with two OR-delimited conditions: one for not-https and the other for wrong-www. If your redirects are happening in a single step--the spurious “error” you reported earlier--the appropriate rule is probably already in place. Just to repeat it here:

RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule (.*) https://www.example.com/$1 [R=301,L]

smallcompany

8:30 pm on Dec 3, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thanks very much for help!

Based on your replies, and some more research and thinking, I've simplified all of the mentioned redirects to this:

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


It's a copy/paste from the net, and I decided to keep it after testing it with redirect tools, plus that HSTS as well (the redirect request for non-WWW then to WWW is gone as I opted for HTTP only version now).

What I'm still curious about is the initial question:

Why my HTML pages are not showing Strict-Transport-Security in their headers, yet files like CSS or JS do show it?

SSL certificate has been installed for a long time, using testing tools for HTTPS shows green marks. What is the actual difference between STS thing and SSL?

Thank you

P.S.
I'm checking on mod_headers now, if it's installed, no idea if that is a default or not.

lucy24

10:23 pm on Dec 3, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I've simplified all of the mentioned redirects to this:
Noooo. Now you're going backward. You need a single rule, with two (or more)* conditions. In addition, the domain-name-canonicalization part needs to be expressed as a negative: “anything other than my preferred form” (with closing anchor to allow for requests with appended port number).

Moreover, the (.*) in the pattern and the %{REQUEST_URI} in the target are redundant. Either capture and reuse, or don't capture in the first place. And never ever put %{HTTP_HOST} in the canonicalization redirect, because the whole point is that there is only one permitted form of the hostname. Rare exception if for some reason you've got dozens of sites sharing a single htaccess, but really it's not worth the trouble. If it's your own server or VPS so it's all happening in config, put a separate rule in each virtualhost envelope.


* When I first set up https sites, I found that some robots seemed to get confused if robots.txt requests got redirected, so I now poke a hole as the first RewriteCond.

smallcompany

6:05 pm on Dec 8, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Noooo. Now you're going backward. You need a single rule, with two (or more)* conditions.


As there were multiple issues here, the decision is to stick to non-www version from now on. Having that in mind, plus to avoid multiple redirects, this is what I have now, two conditions, one rewrite:

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,NE,R=301]


To be honest, I'm not capable of knowing exactly what such and similar rules do, but after testing it, it seemed to redirect all to the desired HTTPS non-WWW version.

Two questions:

1. What would be the difference between when I use $1 vs %{REQUEST_URI}?
2. I still have trouble with getting STS resolved which was the main reason for this post. No HSTS header is present

P.S.
I have removed the old canonicalization entries since I achieve the goal now without them anyway.

lucy24

6:47 pm on Dec 8, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



What would be the difference
$1 means “reuse material that was captured in the Pattern part of the RewriteRule”.
%{REQUEST_URI} means, functionally, the same thing--except that instead of getting it from the rule you’re currently in, the server pulls it from some other source.
There probably exist benchmark tests on which version is most efficient. I'm inclined to think it is a matter of nanoseconds; it may not even be a question of time but of which version uses fewer server resources.

Why did you add the NE flag? The NS flag might conceivably be relevant--it saves the server the trouble of evaluating conditions when you already know they will fail--but ordinarily NE is only needed when you've got a special character in the Target. (For example, if you're redirecting to an on-page fragment.)

smallcompany

7:11 pm on Dec 8, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Why did you add the NE flag?

Copy/paste disease. Deleted now.

But, about NS, do you think it should be here? I do use PHP Include in my HTML for some small portions of code or just to echo html. Would that be a sub-request?

Thanks!

lucy24

8:11 pm on Dec 8, 2018 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Would that be a sub-request?
Not sure about that, frankly, but I kinda think not, since php stuff is done by its own file, not by the server itself.

The NS flag covers requests by other mods, notably mod_index serving up the index.html file when you request the directory, and also SSIs--which are different from php includes. In the rule we've been talking about, the NS flag may or may not make a difference but it definitely can't do any harm. (The typo NE flag also won't do any harm, unless you've got really bizarre URLpaths; it's just unnecessary.)