Welcome to WebmasterWorld Guest from 54.172.221.7

Forum Moderators: phranque

Strict-Transport-Security for all but HTML page

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

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 2, 2006
posts:2239
votes: 8


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
12:42 am on Nov 29, 2018 (gmt 0)

Administrator from US 

WebmasterWorld Administrator not2easy is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Dec 27, 2006
posts:4119
votes: 260


Are all the files in one single directory or are they in various folders? Rewrite is not always inherited in subfolders.
1:09 am on Nov 29, 2018 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 2, 2006
posts:2239
votes: 8


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.
4:04 am on Nov 29, 2018 (gmt 0)

Administrator from US 

WebmasterWorld Administrator not2easy is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Dec 27, 2006
posts:4119
votes: 260


Do the html pages have http: links on the pages?
4:48 am on Nov 29, 2018 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:15374
votes: 725


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.
8:52 pm on Dec 2, 2018 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 2, 2006
posts:2239
votes: 8


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
10:32 pm on Dec 2, 2018 (gmt 0)

Administrator from US 

WebmasterWorld Administrator not2easy is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Dec 27, 2006
posts:4119
votes: 260


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.
12:06 am on Dec 3, 2018 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:15374
votes: 725


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]
8:30 pm on Dec 3, 2018 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 2, 2006
posts:2239
votes: 8


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.
10:23 pm on Dec 3, 2018 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:15374
votes: 725


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.
6:05 pm on Dec 8, 2018 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 2, 2006
posts:2239
votes: 8


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.
6:47 pm on Dec 8, 2018 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:15374
votes: 725


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.)
7:11 pm on Dec 8, 2018 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 2, 2006
posts:2239
votes: 8


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!
8:11 pm on Dec 8, 2018 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:15374
votes: 725


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.)