Secure Cookies not working with hostname set in hosts file - cookies

I have cookies set as secure, but it's working as localhost. But with the domain name set in the hosts file, chrome is not sending the cookies to server resulted in request failing.
i am running my server on the localhost with the following cookie set, the cookie is being sent by chrome to my server.
cookie := http.Cookie{Name: "XSRF-TOKEN", Value: csrf.Token(r), Expires: expiration, Path: "/", HttpOnly: false, Secure: true}
I have set the following in my host file and trying to open from chrome x.test.in the cookie is not getting passed . chrome reporting as set-cookie was blocked because it has the secure attribute but was not received the following code is in golang and using gorilla mux
127.0.0.1 x.test.in

Did you call the server with HTTP or HTTPS? If the "Secure" Flag is set on the cookie it can only be set after an HTTPS call
If it was indeed blocked by Chrome you can still see it by going into the "Network" Tab of your developer tools, select the request, click on "Cookies" and select "show filtered out request cookies". The blocked cookie should appear and you should see there why this was the case.

You can try this in an other browser. I think chrome means, the cookie is a fake-secure cookie.

Related

Flask session lost after redirect - seems like browser doesn't set the cookie. What am I missing?

I have a web app that makes a POST request to:
https://localhost:5000/processOneTapCredentials
This endpoint sets some data in flask.session, and then returns a redirect to another endpoint (https://localhost:5000/login/success). I can confirm it attempts to set the session. The response headers for the first endpoint (the 302 response) includes:
On the second endpoint, the session is empty though. I see that when the 302 is processed, there is no cookie header set in the headers:
So the flow is:
Web app makes a XHR request (POST) to https://localhost:5000/processOneTapCredentials
https://localhost:5000/processOneTapCredentials sets some flask.session info and returns a 302 to https://localhost:5000/login/success
https://localhost:5000/login/success gets invoked (I see in dev tools), but there is no cookie, so session is empty.
I have set the Flask key correctly, and the session works between redirects in other situations (such as when Flask-dance redirects to authenticate a user). So I must be doing something wrong.
What am I missing?
make sure your app['SECRET_KEY'] is not changing, and if you are redirecting to an external website or redirect from http to https you need to set your SAMESITE policy properly, with a SAMESITE='Lax' cookies are not forwarded, try setting it to None and see it the problem is related to your SAMESITE policy

Cookie not being set on angular client

I have a backend app in django python and it is being served on http://localhost:8000.
I have a angular frontend which is being served on http://localhost:4200.
I have disabled CORS on django.
On hitting the login api on http://localhost:8000/auth/login/, I am getting a valid response
along with the Set-Cookie header.
Here is my angular code to print the cookies:
this.http.post<any>('http://localhost:8000/auth/login/', this.LoginForm, { observe: 'response' }).subscribe(response => {
console.log("response is ", response);
var cookies = this.cookieService.getAll();//('cookies');
console.log("cookies is :", cookies);
It prints an empty object on console.
How do I make this work? I want to use cookies for authentication.
You are trying to set cross domain cookies, which will not work straight away. There are a few steps to follow to be able to do that.
Set withCredentials: true when making the authentication request from angular
this.http.post<any>('http://localhost:8000/auth/login/', this.LoginForm, { observe: 'response', withCredentials: true })
Configure your server to return the following CORS headers: Access-Control-Allow-Credentials: true and Access-Control-Allow-Origin: http://localhost:4200
Note
One of the cookies that you are setting is HttpOnly. As such, you cannot access it from Javascript (see documentation).
You may not need to access the cookies with JS anyway. If you just want to send the cookies in the next API requests, just pass withCredentials: true to HttpClient other api calls
this.http.get('http://localhost:8000/path/to/get/resource',
{ withCredentials: true }).subscribe(response => {
Set-Cookies:
In the example in the Question, both client and server are in the same domain, localhost.
On deployment, this may not be the case.
Let us assume the domains as below,
Client : client1.client.com
Server: server1.server.com
A http request from the Angular web app in client1.client.com to https://server1.server.com/api/v1/getSomething has Set-Cookie: JSESSIONID=xyz in the response header.
The cookie will be set on server1.server.com and NOT on client1.client.com.
You can enter server1.server.com in the URL bar and see the cookie being set.
withCredentials:
There is no need for the angular app to read the cookie and send it in the following requests. withCredentials property of http request can be used for this.
Refer: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
Example:
public getSomething(): Observable<object> {
const httpOptions = {
withCredentials: true
};
return this.http.get(`${this.serverUrl}/getSomething`, httpOptions);
}
Refer: https://angular.io/api/common/http/HttpRequest
withCredentials will set the cookies from the server's domain in the requests to the server.
As mentioned before Set-Cookie: JSESSIONID=xyz in the response from server1.server.com will be set in server1.server.com. The Angular app in client1.client.com need not read it. withCredentials will take care of it.
cross domain issues:
When the server and client are in different domains, using withCredentials may not work in all browsers, as they are considered as third party cookies.
In my recent testing on May 2020, I found that withCredentials is not working in certain browsers when the client and server are in different domains.
In Safari, the issue occurs when "Prevent cross-site tracking" is enabled (by default). The issue is prevented by disabling the same. https://support.apple.com/en-in/guide/safari/sfri40732/mac
In Android apps, the issue can be avoided by using Chrome Custom Tabs instead of Android WebView. https://github.com/NewtonJoshua/custom-tabs-client , https://developer.chrome.com/multidevice/android/customtabs
Same domain:
Looks like mainstream browsers are moving to block third-party cookies.
Safari - Full Third-Party Cookie Blocking and More
Chrome (by 2022) - Building a more private web: A path towards making third party cookies obsolete
The solution is to have both the client and server in the same domain.
Client: client1.myapp.com
Server: server1.myapp.com
And in the Set-Cookie response include the root domain too.
Example: "JSESSIONID=xyz; Domain=.myapp.com; Path=/"
This will make sure the cookies are set in all cases.

How to make a cookie available to all paths in a domain?

I created a cookie in a java filter and added back to the response
response.addCookie()
before returning to the client node.js application. This web application is accessed using a localhost URL in the browser. After reading about cookie domain issue while using 'localhost', i did not set any domain or path in the cookie, while creating it.
Now the Chrome or Firefox browsers don't show-up the cookie in the browser. All my URLs are http://localhost but, each page having different path.
Step 1: During a request to http://localhost/app/login cookie is created and set in the response
Step 2: When the page loads after response, no cookies are shown in Chrome
Step 3: During the next request http://localhost/app/customer the previously created cookie is not recieved when trying request.getCookies().
Step 4: Before returning back to client application, a cookie is created
Step 5: Now the cookie created in Step 4 is shown in Chrome
Step 6: The next request is also sent to http://localhost/app/customer , now the cookie created in step 4 is recieved in the server as well
If cookie creation for localhost is an issue, how does it work for Steps 4-6 only ?
How can i make the created cookie available to all paths under the
localhost domain ? I tried using cookie.addPath("/") but, no change.
Note: Due to admin privilege issues in my development machine, i am not able to set-up a domain name to my localhost IP in etc/hosts file.
In your Java server, you should call cookie.setPath("/") before adding it to response.
Such cookie will match all request URIs. It's a pity that it is not the default behavior.
I have a more detailed explanation of cookie path here - http://bayou.io/release/0.9/javadoc/bayou/http/Cookie.html#path
Not sure path is the issue. Path does not affect whether a cookie is created; it only determines whether it is presented. If cookies aren't showing up in the browser's cookie jar they are being rejected for some reason other than path.
Chrome will not accept cookies for localhost because it does not accept cookies in the top level domain. The domain in the URL has to have a dot in it somewhere. So you could either add a hosts entry (recommended) or just trying using 127.0.0.1 instead of localhost.
Also, none of this will work if the cookie is marked as secure or is being set with a domain attribute. If either of those is the case, you MUST use a hosts entry instead of localhost or 127.0.0.1.

cookie issue with same domain same port but different path

I have a situation where my web application will respond with cookie Rules=abcdefg for each request.
Request 1:
http : //hostname:8080/teja/axftyo (for this request I am setting cookie path as below, response from server)
Set-Cookie: Rules=HCE0F290B77137721C2F6107DD4B62F28;Path="/teja/axftyo"
Request 2:
http : //hostname:8080/teja/bcdefg
I assume that for request 2 Rules cookie should not be sent, but still the browser is sending this cookie in to the server.
How can I achieve the functionality of browser sending different cookies based on the path (/bcdefg) rather by my application name /teja
Thank you.
Cookie paths only work on a directory level. /dir/a and /dir/b are considered to be in the same scope for cookies.
/dir/a/ and /dir/b/, on the other hand, are distinguishable, so you could consider adding trailing slashes to your URLs.

Safari doesn't save cookies on custom https port

I have a web application that i'm looking to access by https on port 444.
In Safari, when accessing it, my initial request logs me in successfully (i can see the authentication success message in custom HTTP response headers).
But the site does not display successfully, because the request for the CSS file associated with the page fails with Access Denied.
Upon inspection of the headers, i can see that a session is assigned to the first request (for the page, with the Set-Cookie response header), and a new session has been assigned for the CSS request (also with the Set-Cookie response header). No cookies show up in the Web Inspector. My assumption is that the cookie from the first request is not being saved and so the server is assigning a new session.
When accessing the site on the standard https port (443), the behavior is as expected, as it is when accessing it on port 444 with Firefox. I'm on OSX Mountain Lion.
Any thoughts much appreciated!