Samesite issue in ios 12 browsers - ios12

I am facing an issue in online payment portal ,when redirecting from merchant portal the session gets timedout in ios 12 browsers, i suspect this due to Samesite attribute not applying properly, currently it has been applied in revreseproxy level,are there any solutions for that ?

I've provided some detail on this here: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
The summary is that you can either:
Set the same data in two separate cookies:
Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure
On the receiving end, you can then check which cookie has been received. If the
legacy cookie is present, then you know you are dealing with an older browser
and can adjust accordingly.
Detect the browser based on the User-Agent value. There's a regular expression you can use here: https://www.chromium.org/updates/same-site/incompatible-clients however any form of User-Agent detection will be fragile, so exercise caution.

Related

One time nonce http digest authentication

I try to implement a one time none for HTTP digest authentication process. First of all I'm aware of the fact that the authentication is not perfectly secure. Please do not tell me to use something else. The authentication process is working as expected. When the user authenticate successfully I append a http Authentication-Info field with the next nonce. The browser in this case Firefox is not using this nonce for further requests.
Authentication-Info: nextnonce="06e8043d3fb8c26156829c4b55afd13040"
Why is the browser not using my new nonce for future requests? It still uses the old now invalid one!
RFC7616 describes the header field.
https://www.rfc-editor.org/rfc/rfc7616#section-3.5
The value of the nextnonce parameter is the nonce the server
wishes the client to use for a future authentication response.
The server MAY send the Authentication-Info header field with a
nextnonce field as a means of implementing one-time nonces or
otherwise changing nonces. If the nextnonce field is present, ...
RFC2617 describes the syntax in section 3.2.3
https://www.ietf.org/rfc/rfc2617.txt
[Edit]
Is it possible that firefox is not supporting this feature. If I search here
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate
for the header field I can't find a result.
But it is listed as standard header flag here:
https://www.iana.org/assignments/message-headers/message-headers.xhtml
nextnonce is not supported in Firefox, not even Authentication-Info header.
The bug "next nonce digest auth test fails" was opened 18 years ago and it's still not fixed yet.
I downloaded the source code of the latest Firefox version 65.0.1 and searched the project. "Authentication-Info" only appears in netwerk/protocol/http/nsHttpDigestAuth.cpp as a comment, nowhere else.

Recommended CORS Allow and Expose Headers

enable-cors.org nginx config suggests using the below values for Access-Control-Allow-Headers and Access-Control-Expose-Headers. But there isn't much explanation of why these are recommended except Custom headers and headers various browsers *should* be OK with but aren't. I'd rather not inflate the payload for every API request if some of these are not needed for my application.
I know I could remove them and wait for something to break but I'm hoping for some background on why/how they were selected so I can make a more educated decision on whether they are necessary for my application. i.e. were they recommended to support a browser that my application doesn't need to support?
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range
Access-Control-Expose-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range
For the Allow-Headers, I can understand for most of them why a client would want to send them. X-CustomHeader stands out as an oddball though. Also, I tested on Chrome that even if User-Agent isn't explicitly allowed, chrome still sends it. This implies that these options were added for browser compatibility that my app might not need.
For the Expose-Headers, it seems like it would be very application specific on which headers a client needs to read. Why would a client need to read User-Agent, DNT, or X-Requested-With? They contain info meant for the server to consume, not the client. Additionally, Cache-Control and Content-Range are already enabled by default so they seem redundant here.
I ended up going through each header and determining if it was necessary. I compiled a list of changes:
Changes for both Allow and Expose
Removed from both since they are non-standard headers
X-CustomHeader
Removed from both since they are non-standard and semi-deprecated
Keep-Alive
Changes for Allow:
Removed since they are response-specific headers (used only for
servers to inform client)
Content-Range
Kept even though they are enabled by default but only for certain
types of requests (as per MDN):
Content-Type
Changes for Expose:
Removed since they are already enabled by default (as per MDN)
Cache-Control
Content-Type
Removed since they are request-specific headers (used only for
clients to inform server)
DNT
User-Agent
X-Requested-With
If-Modified-Since
Range
Added since they seem useful
Content-Length
This leaves me with the following:
Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
Access-Control-Expose-Headers: Content-Length,Content-Range
Any comments or corrections would be greatly appreciated.

cookies - the misunderstanding

My goal is that I want to log into a site with some java code and do some work when logged in. (in order to write some java cooking handling I first need to understand how this all actually works)
The problem is that I can't quite figure out how to manage the cookie session.
Here's what I've observed when using chrome's dev. tools:
1) on first request for the site's url I send no cookies and I get some in response:
Set-Cookie:PHPSESSID=la2ek8vq9bbu0rjngl2o67aop6; path=/; domain=.mtel.bg; HttpOnly
Set-Cookie:PHPSESSID=d32cj0v5j4mj4nt43jbhb9hbc5; path=/; domain=.mtel.bg; HttpOnly
2) on moving on log page I now send (on HTTP GET):
Cookie:PHPSESSID=d32cj0v5j4mj4nt43jbhb9hbc5;
__utma=209782857.1075318979.1349352741.1349352741.1349352741.1;
__utmb=209782857.1.10.1349352741;
__utmc=209782857;
__utmz=209782857.1349352741.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);
__atuvc=1%7C40
and indeed when I check my stored cookies (after my first get request for the site's main url) in chrome's cookie tab - they exist in the way they're passed on the next get/post request.
Can you explain what's really happening after my 1st cookies are received and why such name/value pairs are stored?
There's a Javascript from Google Analytics on the page which sets some cookies.

ASP.NET MVC and IE caching - manipulating response headers ineffective

Background
I'm attempting to help a colleague debug an issue that hasn't been an issue for the past 6 months. After the most recent deployment of an ASP.NET MVC 2 application, FileResult responses that force a PDF file at the user for opening or saving are having trouble existing long enough on the client machine for the PDF reader to open them.
Earlier versions of IE (expecially 6) are the only browsers affected. Firefox and Chrome and newer versions of IE (>8) all behave as expected. With that in mind, the next section defines the actions necessary to recreate the issue.
Behavior
User clicks a link that points to an action method (a plain hyperlink with an href attribute).
The action method generates a PDF represented as a byte stream. The method always recreates the PDF.
In the action method, headers are set to instruct browsers how to cache the response. They are:
response.AddHeader("Cache-Control", "public, must-revalidate, post-check=0, pre-check=0");
response.AddHeader("Pragma", "no-cache");
response.AddHeader("Expires", "0");
For those unfamiliar with exactly what the headers do:
a. Cache-Control: public
Indicates that the response MAY be cached by any cache, even if it would normally be non-cacheable or cacheable only within a non- shared cache.
b. Cache-Control: must-revalidate
When the must-revalidate directive is present in a response received by a cache, that cache MUST NOT use the entry after it becomes stale to respond to a
subsequent request without first revalidating it with the origin server
c. Cache-Control: pre-check (introduced with IE5)
Defines an interval in seconds after which an entity must be checked for freshness. The check may happen after the user is shown the resource but ensures that on the next roundtrip the cached copy will be up-to-date.
d. Cache-Control: post-check (introduced with IE5)
Defines an interval in seconds after which an entity must be checked for freshness prior to showing the user the resource.
e. Pragma: no-cache (to ensure backwards compatibility with HTTP/1.0)
When the no-cache directive is present in a request message, an application SHOULD forward the request toward the origin server even if it has a cached copy of what is being requested
f. Expires
The Expires entity-header field gives the date/time after which the response is considered stale.
We return the file from the action
return File(file, "mime/type", fileName);
The user is presented with an Open/Save dialog box
Clicking "Save" works as expected, but clicking "Open" launches the PDF reader, but the temporary file IE stored has already been deleted by the time the reader tries to open the file, so it complains that the file is missing (and it is).
There are a half dozen other apps here that use the same headers to force Excel, CSV, PDF, Word, and a ton of other content at users and there's never been an issue.
The Question
Are the headers correct for what we're trying to do? We want the file to exist temporarily (get cached), but always be replaced by new versions even though the requests may be identical).
The response headers are set in the action method before return a FileResult. I've asked my colleague to try creating a new class that inherits from FileResult and to instead override the ExecuteResult method so that it modifies the headers and then does base.ExecuteResult() instead -- no status on that.
I have a hunch the "Expires" header of "0" is the culprit. According to this W3C article, setting it to "0" implies "already expired." I do want it to be expired, I just don't want IE to go removing it off of the filesystem before the application handling it gets a chance to open it.
As always, thanks!
Edit: The Solution
Upon further testing (using Fiddler to inspect the headers), we were seeing that the response headers we thought were getting set were not the ones being interpreted by the browser. Having not been familiar with the code myself, I was unaware of an underlying issue: the headers were getting stomped on outside of the action method.
Nonetheless, I'm going to leave this question open. Still outstanding is this: there seems to be some discrepancy between the Expires header having a value of 0 vs. -1. If anybody can lay claim to differences by design, in regards to IE, I would still like to hear about it. As for a solution though, the above headers do work as intended with the Expires value set to -1 in all browsers.
Update 1
The post How to control web page caching, across all browsers? describes in detail that caching can be prevented in all browsers with the help of setting Expires = 0. I'm still not sold on this 0 vs -1 argument...
I think you should just use
HttpContext.Current.Response.Cache.SetMaxAge (new TimeSpan (0));
or
HttpContext.Current.Response.Headers.Set ("Cache-Control", "private, max-age=0");
to set max-age=0 which means nothing more as the cache re-validating (see here). If you would be set additionally ETag in the header with some your custom checksum of hash from the data, the ETag from the previous request will be sent to the server. The server are able either to return the data or, in case that the data are exactly the same as before, it can return empty body and HttpStatusCode.NotModified as the status code. In the case the web browser will get the data from the local browser cache.
I recommend you to use Cache-Control: private which force two important things: 1) switch off caching the data on the proxy, which has sometimes very aggressive caching settings 2) it will allows the caching of the the data, but not permit sharing of the cache with another users. It can solve privacy problems because the data which you return to one user could be not allowed to read by another users. By the way the code HttpContext.Current.Response.Cache.SetMaxAge (new TimeSpan (0)) set Cache-Control: private, max-age=0 in the HTTP header by default. If you do want to use Cache-Control: public you can use SetCacheability (HttpCacheability.Public); to overwrite the behavior or use Headers.Set instead of Cache.SetMaxAge.
If you have interest to study more caching options of HTTP protocol I would recommend you to read the caching tutorial.
UPDATED: I decide to write some more information to clear my position. Corresponds to the information from the Wikipedia even so old web browsers like Mosaic 2.7, Netscape 2.0 and Internet Explorer 3.0 supports March 1996, pre-standard of HTTP/1.1 described in RFC 2068. So I suppose (but not test it) that the old web browsers support max-age=0 HTTP header. In any way Netscape 2.06 and Internet Explorer 4.0 definitively supports HTTP 1.1.
So you should ask you first: which HTML standards you use? Do you still use HTML 2.0 instead of more late HTML 3.2 published in January 1997? I suppose you use at least HTML 4.0 published in December 1997. So if you build your application at least in HTML 4.0, your site can be oriented on the web clients which supports HTTP 1.1 and ignore (don't support) the web clients which don't support HTTP 1.1.
Now about other "Cache-Control" headers as "private, max-age=0". Including of the headers is in my opinion is pure paranoia. As I have some caching problem myself I tried also to include different other headers, but later after reading carefully the section 14.9 of RFC2616 I use only "Cache-Control: private, max-age=0".
The only "Cache-Control" header which can be additionally discussed is "must-revalidate" described on the section 14.9.4 which I referenced before. Here is the quote:
The must-revalidate directive is necessary to support reliable
operation for certain protocol features. In all circumstances an
HTTP/1.1 cache MUST obey the must-revalidate directive; in particular,
if the cache cannot reach the origin server for any reason, it MUST
generate a 504 (Gateway Timeout) response.
Servers SHOULD send the must-revalidate directive if and only if
failure to revalidate a request on the entity could result in
incorrect operation, such as a silently unexecuted financial
transaction. Recipients MUST NOT take any automated action that
violates this directive, and MUST NOT automatically provide an
unvalidated copy of the entity if revalidation fails.
Although this is
not recommended, user agents operating under severe connectivity
constraints MAY violate this directive but, if so, MUST explicitly
warn the user that an unvalidated response has been provided. The
warning MUST be provided on each unvalidated access, and SHOULD
require explicit user confirmation.
Sometime if I have problem with Internet connection I see the empty page with "Gateway Timeout" message. It come from the the usage of "must-revalidate" directive. I don't think that "Gateway Timeout" message really help the user.
So the persons, how prefer to start self-destructive procedure if he hears "Busy" signal on the call to his boss, should additionally use "must-revalidate" directive in the "Cache-Control" header. Other persons I recommend just use "Cache-Control: private, max-age=0" and nothing more.
For IE, I remember having to set Expires: -1. How to prevent caching in Internet Explorer seems to confirm this with the following code snippet.
<% Response.CacheControl = "no-cache" %>
<% Response.AddHeader "Pragma", "no-cache" %>
<% Response.Expires = -1 %>
Looking back in code, this is what I found. Also, I vaguely remember that if you set Cache-Control: private is may not behave correctly with SSL.
Response.AddHeader("Cache-Control", "no-cache");
Response.AddHeader("Expires", "-1");
Also, So, You Don't Want To Cache, Huh? mentions -1, but uses methods on Response.Cache instead:
// Stop Caching in IE
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
// Stop Caching in Firefox
Response.Cache.SetNoStore();
However, ASP Page caching issue (IE8) says this code doesn't work.

Reason to rename ASP.NET Session Cookie Name?

is there any reason (safety?) why someone should rename the ASP.NET Session Cookie Name or is it just a senseless option of ASP.NET?
If you have several applications running under the same domain on the same server, you may well want to have seperate session cookie names for each one, so that they aren't sharing the same session state or worse still overwriting each other.
See also the notes for the Forms Auth cookie name:
Specifies the HTTP cookie to use for authentication. If multiple applications are running on a single server and each application requires a unique cookie, you must configure the cookie name in each Web.config file for each application.
1) It might (slightly) slow someone down who is (casually) looking for it.
2) You might want to hide the fact that you are running ASP.NET
Below link provides more information about why session cookies should be renamed.
https://www.owasp.org/index.php/Session_Management_Cheat_Sheet
"The name used by the session ID should not be extremely descriptive nor offer unnecessary details about the purpose and meaning of the ID.
The session ID names used by the most common web application development frameworks can be easily fingerprinted [0], such as PHPSESSID (PHP), JSESSIONID (J2EE), CFID & CFTOKEN (ColdFusion), ASP.NET_SessionId (ASP .NET), etc. Therefore, the session ID name can disclose the technologies and programming languages used by the web application.
It is recommended to change the default session ID name of the web development framework to a generic name, such as “id”."
With cookie prefixes, you can add a security attribute to your cookie by naming it a special way. So in that case renaming your ASP.NET session cookie does have an impact on security:
__Secure-… cookies can only be written from secure (HTTPS) sites.
__Host-… cookies can only be written from the same, secure domain. So not from subdomains or insecure (HTTP) sites.
According to the following specification, https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00, that modern browsers implement, the prefixes are used to make things more secure.
3.1. The "__Secure-" prefix
If a cookie's name begins with "__Secure-", the cookie MUST be:
Set with a "Secure" attribute
Set from a URI whose "scheme" is considered "secure" by the user
agent.
The following cookie would be rejected when set from any origin, as
the "Secure" flag is not set
Set-Cookie: __Secure-SID=12345; Domain=example.com
While the following would be accepted if set from a secure origin
(e.g. "https://example.com/"), and rejected otherwise:
Set-Cookie: __Secure-SID=12345; Secure; Domain=example.com
3.2. The "__Host-" prefix
If a cookie's name begins with "__Host-", the cookie MUST be:
Set with a "Secure" attribute
Set from a URI whose "scheme" is considered "secure" by the user
agent.
Sent only to the host which set the cookie. That is, a cookie
named "__Host-cookie1" set from "https://example.com" MUST NOT
contain a "Domain" attribute (and will therefore be sent only to
"example.com", and not to "subdomain.example.com").
Sent to every request for a host. That is, a cookie named
"__Host-cookie1" MUST contain a "Path" attribute with a value of
"/".
The following cookies would always be rejected:
Set-Cookie: __Host-SID=12345 Set-Cookie: __Host-SID=12345;
Secure Set-Cookie: __Host-SID=12345; Domain=example.com
Set-Cookie: __Host-SID=12345; Domain=example.com; Path=/
Set-Cookie: __Host-SID=12345; Secure; Domain=example.com; Path=/
I think its mainly a matter of taste. Some people/companies want control every aspect of their web apps and might just use another name for consistency with other cookie names. For example, if you use very short one-character parameter names throughout your app you might not like session cookie names like ASPSESSID.
Security reasons might apply but security through obscurity is rather weak in my opinion.

Resources