I have 2 asp .net applications running on the same domain (both in staging & production). Application A opens a page from Application B in a popup window. The cookie names for staging and production are different.
But strangely for some users, even though the request is for production, staging cookies are being appended to the request. Is it a cached request being pulled from somewhere? Where the production cookies going? In Application A the cookies are found and they are fine. But Application B is getting the staging/wrong cookies.
Sorry for not sharing any code for confidentiality issues. Here's an example:
In application A, following cookies are there:
BDT, path="/", domain=".sample.com" (this is production)
In application B, cookies are somewhat like this:
SBDT, path="/", domain=".sample.com" (this is staging cookie)
Is the request being cached (at the machine or some proxy server) and being issued repeatedly? Or can it be some mal-ware/virus?
User is using IE9 (in IE7 mode) on Windows 7
finally we cracked it.
We again carefully analyzed the HttpWatch logs and noticed that, the App B is being run in IE protected mode, where as App A is not.
We requested the client to clear the cache and launch the applications again. After that we found that,
App B is getting NO cookies at all
We made a guess that, they are running in IE protected mode with High security level enabled. And they have ONLY 'App A' in the trusted sites list i.e AppA.sample.com
We requested them to add *.sample.com instead and that FIXED the issue.
For more details check:
Persistent cookies are not shared between Internet Explorer and Office applications
Related
I have a baffling issue with cookie handling in a Blazor server app (.NET Core 6) using openid (Keycloak). Actually, more than a couple which are may or may not linked. It’s a typical (?) reverse proxy architecture:
A central nginx receives queries for services like Jenkins, JypyterHub, SonarQube, Discourse etc. These are mapped through aliases in internal IPs where the nginx can access them. This nginx intercepts URL like: https://hub.domain.eu
A reverse proxy which resolves to https://dsc.domain.eu. This forwards request to a Blazor app running in Kestrel in port 5001. Both Kestrel and nginx under SSL – required to get the websockets working.
Some required background: the Blazor app is essentially a ‘hub’ where its various razor pages ‘host’ in iframe-like the above mentioned services. How it works: When the user asks for the root path (https://hub.domain.eu) it opens the root page of the Blazor app (/).
The nav menu contains the links to razor pages which contain the iframes for the abovementioned services. For example:
The relative path is intercepted by the ‘central’ nginx which loads Jenkins. Everything is under the same Keycloak OpenID server. Note that everything works fine without the Blazor app.
Scenarios that cause the same problem
Assume the user logins in my app using the login page of Keycloak (NOT the REST API) through redirection. Then proceeds to link and he is indeed logged in as well. The controls in the App change accordingly to indicate that the user is indeed authenticated. If you close the tab and open a new one, the Blazor app will act as if it’s not logged in while the other services (e.g Jenkins) will show the logged in user from before. When you press the Login link, you’ll be greeted with a 502 nginx error. If you clean the cookies from browser (or in private / stealth mode) everything works again. Or of you just log off e.g. from Jenkins.
Assume that the user is now in a service such as Jenkins, SonarQube, etc. if you press F5 now you have two problems: you get a 404 Error but only on SOME services such as Sonarcube but not in others. This is a side problem for another post. The thing is that Blazor app appears not logged in again by pressing Back / Refresh
The critical part of Program.cs looks like the following:
This class handles the login / logoff:
Side notes:
SaveTokens = false still causes large header errors and results in empty token (shown in the above code with the Warning: Token received was null). I’m still able to obtain user details though from httpContext.
No errors show up in the reverse proxy error.log and in Kestrel (all deployed in Linux)
MOST important: if I copy-paste the failed login link (the one that produced the 502 error) to a "clean" browser, it works fine.
There are lots of properties affecting the OpenID connect, it could also be an nginx issue but I’ve run out of ideas the last five days. The nginx config has been accommodated for large headers and websockets.
Any clues as to where I should at least focus my research to track the error??
The 502 error shows an error at NGINX's side. The reverse proxy had proper configuration but as it turned out, not the front one. Once we set the header size to suggested size, everything played out.
I am building a simple web app using React.js for the frontend and Django for the server side.
Thus frontend.herokuapp.com and backend.herokuapp.com.
When I attempt to make calls to my API through the react app the cookie that was received from the API is not sent with the requests.
I had expected that I would be able to support this configuration without having to do anything special since all server-side requests would (I thought) be made by the JS client app directly to the backend process with their authentication cookies attached.
In an attempt to find a solution that I thought would work I attempted to set
SESSION_COOKIE_DOMAIN = "herokuapp.com"
Which while less than ideal (as herokuapp.com is a vast domain) in Production would seem to be quite safe as they would then be on api.myapp.com and www.myapp.com.
However, with this value set in settings.py I get an AuthStateMissing when hitting my /oauth/complete/linkedin-oauth2/ endpoint.
Searching google for AuthStateMissing SESSION_COOKIE_DOMAIN yields one solitary result which implies that the issue was reported as a bug in Django social auth and has since been closed without further commentary.
Any light anyone could throw would be very much appreciated.
I ran into the exact same problem while using herokuapp.com.
I even posted a question on SO here.
According to Heroku documentation:
In other words, in browsers that support the functionality, applications in the herokuapp.com domain are prevented from setting cookies for *.herokuapp.com
Heroku blocks cookies from frontend.herokuapp.com and backend.herokuapp.com
You need to add a custom domain to frontend.herokuapp.com and backend.herokuapp.com
The entire answer https://stackoverflow.com/a/54513216/1501643
I have two spring boot applications.
module1 running on port 8080
module2 running on port 9090
I have set the ports using this property in application.properties file
server.port=${port:9090}
Both modules have /login, /signup which are accessible without authentication accomplished via the code below.
http.authorizeRequests()
.antMatchers("/signup", "/login").permitAll()
Any other request requires that the user be authenticated.
If i use one module at a time there is no problem,
But if try to use them back and forth at the same time then the problem is that i have to login again to the previous app every time i use the other one.
Eg.
Goto Login page to module1 - (Header response has set jsessionid=XX) ok
Login to module1 - ok
Browse secured content on module1 - ok
Goto Sign Up page on module2 - (Header response has set jsessionid=YY) ok
Try to browse to another secured content on module1 - I have to login again
I'm quite sure it's due to the jessionid being reset by module2.
Are HTTP cookies port specific?
I have read this article which states that cookies are not port specific.
But there must be a solution so that i don't have to login everytime i switch apps.
You need to use different cookie names for the two applications.
There are different ways to do these, the most simple one, for a spring-boot application with version >=1.3 is just setting a property :
server.session.cookie.name = MYSESSIONID
Other ways are described in this post .
Map your applications to different context paths, so the JSESSIONID cookies will be independent; otherwise, the cookie is for the same context, so there is effectively one cookie for both applications. Another solution would be to use different hosts.
Please note that you don't only change context path of the cookie here: if you change context path of your application, Servlet API implementation will handle cookie context path change for you.
I've experimented a bit with same host and different context paths.
I'm currently having two applications launched, both have Servlet API as their base (and JSESSIONID cookie is defined by Servlet API's session mechanics). The applications both run on localhost, on different ports, and with different contexts (/app1 and /app2). I've logged into both applications, and in Chrome's dialog which lists cookies I can see two JSESSIONID cookies: one for localhost and /app1 and another for localhost and /app2.
Then I logout in /app2. Its JSESSIONID is destroyed and recreated with different content (because I've been redirected to the login page again). (Please note that to see that change I had to close Cookies dialog and reopen it as Chrome did not update it on the fly). At the same time, JSESSIONID cookie which belongs to /app1 is intact, and I can proceed working in /app1 (so I was not logged out from it).
UPDATE
One more experiment. I've mapped both appilcation at the same context (/app1). They run on localhost:8084 and localhost:8085. I do the following:
I log into the first application (port 8084)
I log into the second application (port 8085)
I switch back to the first application tab, click any link and see that the session is destroyed (as I am being redirected to login page).
So even if applications run on different ports of the same host with the same context path, they use the same cookie. Basically, this is what was said in Are HTTP cookies port specific? : Cookies do not provide isolation by port
A little summary:
Different hosts: no problem, cookies are different
Different application contexts: no problem, cookies are different
Same host, same application context, different ports: there is only one cookie, and this causes a conflict.
So the recipe is the same as before:
Either use different hosts (that is host names, not including port)
Or use different context paths
Or (as another answer suggests) change cookie name to avoid the conflict
I am developing an app, which I will deploy on Heroku. The app is only used within an iframe on another site, so I don't care about the domain name. I plan to deploy my app on example.herokuapp.com instead of using a custom domain on example.com.
My app uses cookies, and I want to be sure that others cannot manipulate my cookies to protect my app against session fixation and similar attacks. If attacker.herokuapp.com is able to set a cookie for herokuapp.com, browsers will not be able to protect me, since herokuapp.com is not a public suffix. See http://w2spconf.com/2011/papers/session-integrity.pdf for a detailed description of the issue.
My question is: When browsers can't protect my users, will Heroku do it by blocking cookies for herokuapp.com?
Just wanted to post an update for anyone who ran across this question as I did. I was working on a similar problem, except that I wanted to purposefully allow access to the same cookie from two different heroku apps.
"herokuapp.com" and "herokussl.com" are now on the Public Suffix List, so your cookies should be safe if they are set for one of those domains. I ended up having to use custom domains in order to share cookies across both apps.
Heroku also released an article on the topic: https://devcenter.heroku.com/articles/cookies-and-herokuapp-com
I just tried to add a cookie from my Heroku app with the response header Set-Cookie: name=value;Path=/;Domain=.herokuapp.com, and to my disappointment, I could see the header intact in my browser. So the Heroku infrastructure does not detect and remove this cross-app supercookie.
I see three possible ways to protect a Heroku app against cross-app supercookies:
Don't use cookies at all.
Use a custom domain.
Verify that each cookie was actually set by your app, and restrict it to the client's IP address by checking the X-Forwarded-For header.
My feature request to Heroku would be that they should filter HTTP responses that goes through their HTTP routing, such that applications hosted on their infrastructure cannot set cookies with Domain=herokuapp.com.
It seems to me that, as long as you set the cookie for example.herokuapp.com, then the cookie is safe from manipulation. The cookie will only be presented to the app running on example.herokuapp.com and to herokuapp.com (where no app runs).
Our web app restricts access to authenticated users; our servers are configured to refuse access to any resource requests unless the HTTP request includes the session cookies. We use a Java applet, for which access to the JAR file is also prevented unless the request has the correct session cookies set.
This works fine for all major browsers we have tried on Windows clients except for Safari (don't have a Mac to test Safari on this). All page resources e.g., html, js, images, ..., load fine; except for the JAR file, where our server returns a 'not authorised' page which obviously doesn't work in the applet container.
It looks like the JVM isn't sending the session cookies when it requests the JAR. I suspect that Safari isn't sharing the cookies with the JVM, because everything works OK in other browsers with the same JVM (IE, Chrome, Fx).
Is there anything we can do to fix this? Or work around this? We can't make the JAR available to non-authorised users due to licensing issues, nor can we change the hosting environment.