Etags and last-modified over https SSL? - caching

Is it possible to use HTTP caching for conditional GET requests over a secure HTTPS connection? I've got caching working over non-secure HTTP, but when I switch to HTTPS the browser stops sending if-none-match and if-modified-since headers, so the caching breaks. I've tried various Cache-Control settings like public, max-age=3600 and whatnot, no dice.
This happens in both Safari and Chrome, so I'm assuming the SSL is breaking it somehow. Is caching not allowed over SSL?
And just to be clear, the server is indeed properly setting the etag and last-modified headers, but the browser is not sending if-none-match and if-modified-since in the request, according to the Chrome developer tools.
Thanks for your help.

Figured it out! Turns out you have to have a trusted certificate. I was using my self-signed test certificate for SSL HTTPS. Adding it to my keychain and turning it green made the caching work.

Related

IE11 AJAX request from HTTP to broken cert HTTPS

I'm currently trying to make an AJAX request in a crappy dev environment. My current app is on HTTP and is making an AJAX request to an HTTPS endpoint with a broken certificate. Is there any way I can get my IE11 to stop rejecting the request?
Found a solution for fixing the messed up SSL cert situation here: https://medium.com/#ali.dev/how-to-trust-any-self-signed-ssl-certificate-in-ie11-and-edge-fa7b416cac68

Firefox SPNEGO Negotiate protocol - multiple connections?

I'm using gssapi/Kerberos authentication in my web application, and I want single sign on via the browser.
The problem is, Firefox sends an initial request to the server with no authentication, and receives a 401. But it includes a keep-alive header:
Connection: keep-alive
If the server respects this keep-alive request, and returns a WWW-Authenticate header, then Firefox behaves correctly and sends the local user's Kerberos credentials, and all is well.
But, if the server doesn't keep the connection alive, Firefox will not send another request with the credentials, even though the response has the WWW-Authenticate header.
This is a problem because I'm using Django, and Django doesn't support the keep-alive protocol.
Is there a way to make Firefox negotiate without the keep-alive? In the RFC that defines the Negotiate extension, there's nothing about requiring that the same connection be re-used.
Alternatively, is there a way to make Firefofx preemptively send the credentials on the first request? This is explicitly allowed in the RFC.
That header is HTTP 1.0, wake up, fast-forward 15 years and your problems will go away. Firefox works very well with SPNEGO.

What key do browsers use to encrypt HTTPS requests to preloaded HSTS sites?

As far as I know, HTTPS requests are regular HTTP requests encrypted with the public key provided by the server during the initial handshake.
I have been reading about HSTS but have not been able to find anything related to the public key of sites that are in preloaded HSTS lists. Are the public keys of these sites also preloaded? Or is this key sent by the server on initial handshake like in any HTTPS request?
is this key sent by the server on initial handshake like in any HTTPS request?
Yes. HSTS just says “always use HTTPS for this domain so automatically correct any http:// calls to https:// before it is sent”.
It says nothing about how that HTTPS connection is set up, which is done through the usual manner.

CORS with client https certificates

I have a site with two https servers. One (frontend) serves up a UI made of static pages. The other (backend) serves up a microservice. Both of them happen to be using the same (test) X509 certificate to identify themselves. Individually, I can connect to them both over https requiring the client certificate "tester".
We were hiding CORS issues until now by going through an nginx setup that makes the frontend and backend appear that they are same Origin. I have implemented the headers 'Access-Control-Allow-Origin', 'Access-Control-Allow-Credentials' for all requests; with methods, headers for preflight check requests (OPTIONS).
In Chrome, cross-site like this works just fine. I can see that front-end URLs and backend URLs are different sites. I see the OPTIONS requests being made before backend requests are made.
Even though Chrome doesn't seem to need it, I did find the xmlhttprequest object that will be used to perform the request and did a xhr.withCredentials = true on it, because that seems to be what fetch.js does under the hood when it gets "credentials":"include". I noticed that there is an xhr.setRequestHeader function available that I might need to use to make Firefox happy.
Firefox behaves identically for the UI calls. But for all backend calls, I get a 405. When it does this, there is no network connection being made to the server. The browser just decided that this is a 405 without executing any https request. Even though this is different behavior from Chrome, it kind of makes sense. Both the front-end UI and backend service need a client certificate to be chosen. I chose the certificate "tester" when I connected to the UI. When it goes to make a backend request, it could assume that the same client certificate should be used to reach the back-end. But maybe it assumes that it could be different, and there is something else I need to tell Firefox.
Is anybody here using CORS in combination with 2 way SSL certificates like this, and had this Firefox problem and fixed it somewhere. I suspect that it's not a server-side fix, but something that the client needs to do.
Edit: see the answer here: https://stackoverflow.com/a/74744206/537554
I haven't actually tested this using client certificates, but I seem to recall that Firefox will not send credentials if Access-Control-Allow-Origin is set to the * wildcard instead of an actual domain. See this page on MDN.
Also there's an issue with Firefox sending a CORS request to a server that expects the client certificate to be presented in the TLS handshake. Basically, Firefox will not send the certificate during the preflight, creating a chicken and the egg problem. See this bug on bugzilla.
When using CORS with credentials (basic auth, cookies, client certificate, etc.):
Access-Control-Allow-Credentials must be true
Access-Control-Allow-Origin must not be *
Access-Control-Allow-Origin must not be multi-value (neither duplicated nor comma-delimited)
Access-Control-Allow-Origin must be set to exactly the value from the request's Origin header in order for the request to work (either hard-coded that way or if it passes a whitelist of allowed values)
The preflight OPTIONS request must not require credentials (including the client certificate). Part of the purpose of the preflight is to ask what is allowed in a CORS request, and therefore sending credentials before knowing if they are allowed is incorrect.
The preflight OPTIONS request must return a 200-level response, generally 204
Note: For Access-Control-Allow-Origin, you may want to consider allowing the value null since redirect chains (like the ones typically used for OAuth) can cause that Origin value in a request from a browser.

chrome browser not sending 'If-None-Match' for xhr

I'm using an angular service to GET a resource via a rest api. The server sets the ETag header to some value and it also sets Cache-Control: no-cache in it's response.
This works as expected using Firefox, but when I access the same app using Chrome, it is not sending the If-None-Match. I've tried on current Chrome dev and stable channels on both a Mac and an Ubuntu box, and it was the same on both, while Firefox was adding the If-None-Match correctly.
Now, there are other non-xhr/static resources that are fetched conditionally and all those requests correctly get a 304 NOT MODIFIED response.
Is there anything I can do to get more information about why Chrome is not sending the If-None-Match header only for XHR requests?
If you're issuing an Ajax query in Chrome over HTTPS, any certificate errors, such as using a self-signed cert on your API server, prevent the response from being cached. This seems to be by design.
Evidently a Chrome defect existed but was fixed in Webkit and made it into Chromium / Chrome around 2010.
Another question recommends setting the If-Modified-Since and If-None-Match headers manually using jQuery's ifModified: true and cache: true options. Unfortunately this won't over-ride Chrome's intended behavior to not cache HTTPS responses from a server with a self signed certificate.
Testing on a server with a valid signed SSL certificate solved the issue for me; Chrome received 304's for text/html content as expected, using the default jQuery AJAX methods.

Resources