Preventing Safari prefetching web pages (server side) - http

When typing a web link into the safari URL field, the browser attempts to prefetch all links it has previously seen before, both GET and POST.
This causes each and every web link a server supports that is listed in the dropdown as a possible completion to be activated. This is problematic. For example, if a web site has authentication with an /auth/logout link for logging out, then this can cause the link to be activated if it appears in the dropdown, logging the user out unintentionally.
Many browsers send a specific header (eg. 'Purpose: Prefetch' in chrome) that allows the server side to filter prefetch/preload requests (eg. return a 503) but Safari doesn't seem to send any distinguishing header field. It also seems to try to prefetch POST requests, which seems very broken to me. Get requests are notionally at least idempotent, but POST requests are supposed to be understood to be data changing.
Has anyone got a solution to this? Please don't suggest that the browser preload feature can be turned off by the end user - that ISN'T a solution from a service delivery perspective.
Has anyone got an explanation as to why browsers would do this and NOT signal the purpose in a header field? (I get why prefetching is a useful Ux capacity, but not why its useful while typing URLs, especially for URLs already previously downloaded and thus capable of returning prefetching metadata that would allow a server to selectively disable the capability where appropriate) From what I can tell, this kind of functionality started to appear with header fields included, but some browsers have removed this signature. why? It seems to be dreadfully broken to me.
thanks.

Related

Why don't modern web browsers display the "realm" value for HTTP authentication anymore?

When hosting a website using HTTP Authentication, if the client has not authenticated, the server will send a 401 Unauthorized response, including a WWW-Authenticate header. An optional directive in this header is realm:
A string describing a protected area. A realm allows a server to partition up the areas it protects (if supported by a scheme that allows such partitioning), and informs users about which paricular username/password are required.
(emphasis mine)
Let's say www.example.com requires authorization and has configured a realm value of Test Area. Back in the day, most web browsers would display a login dialog when receiving such a response, and say something along the lines of "Authorization required. The site at www.example.com says 'Test Area'."
But (at least recent versions of) Chrome, Firefox, and Edge, now all just display a generic message, without including the realm value. Interestingly enough, IE still displays the realm value (screenshots below, all Windows 10 64bit):
Chrome (v93.0.4577.82)
Firefox (v92.0)
Edge (v93.0.961.52)
IE (v11.1411.18362.0)
I'm pretty sure Firefox and Edge used to display it. Chrome may have a while back but seems like it was the first to stop. Since all modern browsers aren't displaying it, I assume there's some reason why..?? I've search all over the internet, and can't figure it out. I have a use-case where it would be helpful to users to have the realm displayed, as it would make it clearer which particular credentials they need to use. I know that you can't force the browser to display it, but it's just annoying. However if there is a valid reason for it not being shown I'll accept that.
The reason is that this could be abused for phishing attacks, by putting some misleading message into the realm. The login dialog for http authentication is part of the trusted browser UI, and giving the server the opportunity to modify that UI - even by just displaying text - is a security risk.

Last-modified cache does not show when user has logged-in

I am using the last-modified HTTP header to help browsers with caching and I have noticed an annoying problem.
If a user visits a page BEFORE he has logged in, then the browser is showing the cached page even after the user logs-in. This means he is unable to see his log-in information (profile pic, notifications etc) in the header until he visits a page on the site he has not visited before.
Because the content of the actual article itself has not changed since his first visit, he is served up the same page even if he logs-in.
I have tried checking to see if the user has just logged-in (using a SESSION.LoggedIn variable), and then use the current DateTime for Last-Modified, Expires and Cache-Control to tell the browser to serve up a fresh copy of the page but it doesn't work on the Android browser. It just serves the cached version again. What this means is that the user cannot tell that they have logged-in because their name and other credentials don't appear at the top of the page.
How do I use HTTP header caching effectively and also take care of people visiting the same page as both logged-in and anonymously? The logged-in information sits in the header of the site (just like on SO) so is there a way not to cache the siteheader but the rest of the page?
Use a tool like firebug to see the network traffic for a URL. You'll notice that it is 'file' objects: html files, javascript files, css files, images, etc.
I don't think that you can cache a div (or other page layout construct) very easily.
It has been a while since I attempted to use the last-modified HTTP header for caching. I ran into similar problems that you have. Browser implementation/compatibility wasn't 100%. I've also used last-modified in an attempt to inform search engine spiders that files have changed. That didn't work very well either. Eventually I removed all of my attempts at last-modified caching/hinting and just allow the web server and browsers to deal with it.
Eventually I ended up spending a lot of time optimizing database queries, database indexes, and in a few cases implemented the cachedwithin attribute of cfquery tags. This attempt at improving site performance has worked better for me.

Chrome and Firefox caching a 403

I've got a weird bug and wondered if anyone else can think of a cause.
Scenario: -
User tries to access restricted content, gets a turn away page with 403 status code
User logs in
User tries to access content again but should be allowed, browser returns cached turn away page and 403 response (no hit registered on server).
CTRL+F5 or wait a while, browser returns correct content.
This is happening in Firefox and Chrome, I haven't tried Internet Exploder.
I have only reproduced the issue once on my machine whilst on a Skype call with the testers, they can reproduce it every time. They are based over in India though and have a much slower connection to our test site. Could that be a cause?
I saw a related question but that was caused by Squid proxy, i'm not behind a proxy (although testers might be).
I'm loathe to add cache control headers as browsers shouldn't cache a 403 according to the HTTP spec but I need to guarantee with that when a user logs in they get the correct content.
Any thoughts on what might be the cause would be greatly appreciated. In the meantime I'll add some cache control headers to the turn away page just to see if that helps.

easiest way to find the HTTP include in a HTTPS throwing security warning?

I often have to go into other people's work to make modifications for short-term contracts and a lot of times I have to deal with security warnings throwing in IE because something is including HTTP content from maybe an image, or css or whatever, onto a HTTPS secure page.
I was just curious if there is a well known program or service that will scan a URL and come back with exactly what is coming from HTTP instead of HTTPS on a page?
I use fiddler, but for reasons having to do with my own inadequacies, I find the program difficult at times, and am un-able to zero in on the offending content in a timely manner.
Any advice from the true pros?
Using Fiddler:
In main menu > Tools > Fiddler options, tab HTTPS, uncheck Capture HTTPS CONNECTs. Then, in main menu > Rules, check Hide HTTPS CONNECTs.
This way, the only thing you'll see in your Fiddler capture will be the HTTP requests and responses (without the HTTPS requests or CONNECTs getting in the way).
I would load up the page in Firefox and use Firebug's Net panel to examine all the resources that the page loads.
There's no 'set in stone' way as far as I know, but the easiest way I know of is to either use a tool such as Opera Dragonfly or Chrome's Web Inspector, view the 'Network' tab and see where the resources are being loaded from. You can sometimes (depending on what you use) order this alphabetically and you will clearly see between http:// and https://.
Also as already mentioned, you could just search the source for http://.

ASP.NET application exhibits strange behaviour through firewall

This problem has been solved thanks to your suggestions. See the bottom for details. Thanks very much for your help!
Our ASP.NET website is accessed from several specific and highly secure international locations. It has been operating fine, but we have added another client location which is exhibiting very strange behaviour.
In particular, when the user enters search criteria and clicks the search button the result list returns empty. It doesn't even show the '0 results returned' text, so it is as if the Repeater control did not bind at all. Similar behaviour appears in some, but not all, other parts of the site. The user is able to log in to the site fine and their profile information is displayed.
I have logged in to the site locally using exactly the same credentials as them and the site works well from here. We have gone through the steps carefully so I am confident it is not a user issue.
I bind the search results in the Page_Load of the search results page the first time it is loaded (the criteria is in the query string). i.e.
if (!IsPostBack) {
BindResults();
}
I can replicate exactly the same behaviour locally by commenting out the BindResults() method call.
Does anybody know how the value of IsPostBack is calculated? Is it possible that their highly-secure firewall setup would cause IsPostBack to always return true, even when it is a redirect from another page? That could be a red herring as the problem might be elsewhere. It does exactly replicate the result though.
I have no access to the site, so troubleshooting is restricted to giving them instructions and asking for them to tell me the result.
Thanks for your time!
Appended info: Client is behind a Microsoft ISA 2006 firewall running default rules. The site has been added to the Internet Explorer trusted sites list and tried in FireFox and Google Chrome, all with the same result.
SOLUTION: The winner for me was the suggestion to use Fiddler. What an excellent tool that no web developer should be without. Using this I was able to strip various headers from the request until I reproduced the problem. There were actually two factors that caused this bug, as is so often the case with such confusing issues.
Factor one – Where possible the web application uses GZIP compression as supported by all major browsers. The firewall was stripping off the header that specifies GZIP decompression support (Accept-Encoding: gzip, deflate).
Factor two – A bug in my code meant that some processing was bypassed when the content was being sent uncompressed. This problem was not noticed before because the application is used by a limited audience, all of which supported GZIP decompression.
If they're at all tech-savvy, I would have them download Fiddler or something similar, capture the entire HTTP session, and then send you the saved session. Maybe something in there will stick out.
Meanwhile, see if you can get an install of ISA Server (an evaluation install, if you have to, or one from MSDN if you have or know anyone with a sub) and see if you can replicate it locally.
Is it possible the client has disabled Javascript and it's not picking up the _EVENTTARGET form value?
It might be some sort of proxy which creates a GET request out of a given POST request...
I am not sure how the IsPostBack is calculated, but my guess would be that it checks the HTTP request to see if it's a POST or a GET...
Ohh, yeah. It's definitely NOT "_EVENTTARGET" BTW...
I know this since Ra-Ajax does NOT pass any of those parameters to the server and they (Ra-ajax requests) are processed as IsPostBack requests...
Location, location, location. Check the user's culture. Normally that causes issues.
Could you create a test Post Page that passes the same things that your search page does, and in the Page_Load write back all of the post to make sure they are getting passed, particularly the __VIEWSTATE.
foreach (string key in Request.Form)
{
Response.Write("<br>" + key + "=" + Request.Form[key]);
}
Then ask one of the users to forward back what they see on that test page.
EDIT: There is documentation that some firewalls can corrupt the VIEWSTATE and some methods to get around it: View State Overview
Check the IIS logs to see if the request even makes it to your server. The ISA setup might be caching the initial request and serving that up in the succeeding requests.

Resources