I've been tasked with modifying an application, of which I have access to the XML configuration of it in what appears to be Tomcat 7.
I need a cookie (called oname to be specific) shared to another domain (example.com). That is to say that, an iframe on the application to example.com can share the cookies from the application.
First of all, is this possible? Second of all, if it is (which I hope it is! :)) how can I do it via XML and XML only (referring to the configuration files found in the base of the application).
I've done some research on cookies, and I determined I need to modify the domain section on all cookies. If I need to change change all cookies globally (e.g. adding an XML element within the configuration to add domain = example.com to all cookies then that's acceptable!
I've pretty much have 2 options:
Find a specific XML element to change all cookies globally to add my desired domain
Have a JavaScript shim on the client side (I have access to the HTML also) wrap around the normal method to set cookies, while also adding example.com to the domain bit on the cookies.
Thanks for any help!
If your application is running on www.example.com, it can set a cookie for .example.com, but not if it's running on any other domain than example.com. If it would be possible to set cookies for unrelated domains, Anybody could easily set a cookie for any other random site, and as cookie names are typically well predictable, interfere with those sites (e.g. setting jsessionid or other session- and identification cookies in a rogue way).
Your only option is if the other site cooperates and provides a URL that you can redirect to which sets the cookie itself. Beware: Without checking the validity of the request, anybody can redirect to that site and set a cookie through the same measures - you can easily introduce a security issue.
Related
I have two applications running in Jboss, can I write a cookie in a application and read in another?
For example, if I have two Servlets:
- WriterCookieServlet on localhost:8080/Application1
- ReaderCookieServlet on localhost:8080/Application2
WriterCookieServlet:
Cookie cookie = new Cookie("cookie", "cookieValue");
response.addCookie(cookie);
response.sendRedirect("localhost:8080/Application2");
Then on ReaderCookieServlet I want read this cookie.
I think #galuano1 is right: this should indeed be possible. Make sure the path is correct, though. It is used to determine whether a certain cookie is visible to a web-application.
From the Cookie Javadoc:
The cookie is visible to all the pages in the directory you specify, and all the pages in that directory's subdirectories. A cookie's path must include the servlet that set the cookie, for example, /catalog, which makes the cookie visible to all directories on the server under /catalog.
Consult RFC 2109 (available on the Internet) for more information on setting path names for cookies.
I'd say you should use / for directory, since both applications will have a different context root.
As long as the domain specified in the cookie is same ( here localhost ) , cookie can be read by the two different applications
It is true: cookie can thoerically be read by the application if it comes from the same domain. This mean that the application has it available, it doesn't imply the application has available the secrets needed to interpret it
The problem here may not be related to the theorical part but on the technology part: if the cookie is not in clear text (as it should be) it requires to be opened by the target application who needs to read the content
This usually comes out of the box if the application which forge the cookie is the same application that needs to read it.
But if it is forged by an application 1 and needs to be decrypted by an application 2, you need to ensure this command you used:
Cookie cookie = new Cookie("cookie", "cookieValue");
doesn't use any application specific secret to encrypt the cookie, otherwise it can never be opened by a different application.
Of course the answer may change according the technology you are using, don't know the behaviour in Java, I am aware many technologies to use machine based secrets to encrpyt and sign the cookie.
I have a service on Tomcat available at the following domains:
sub1.domain1.com
sub2.domain1.com
sub1.domain2.com
sub2.domain2.com
Now I need transparent authorization (Spring Security) for domain1. If user logs in to the sub1.domain1.com he is authorized on sub2.domain1.com too.
This can be done with Tomcat's setting
sessionCookieDomain=".domain1.com"
But now authorization on sub1.domain2.com doesn't work at all because all JSESSIONID cookie domain is always set to ".domain1.com".
How could I make tomcat use only second level of current domain for the cookies?
The simple answer is that there is no simple answer. Essentially you need a primary login site, and scheme whereby secondary sites get to set cookies for their domain that clone the primary site's session token. Implementing this is complicated.
Two possible SSO technologies are Shibboleth and JASIG CAS.
For more details, refer to the answers to Single Sign On across multiple domains
What if I somehow overload cookie creation and set .domain1.com and .domain2.com where required?
If foo.domain1.com tries to set a cookie with path .domain2.com or anything.domain2.com, the browser will ignore it for security reasons. You have to go through a complex dance of redirections to set the cookies on both domains. Read the question / answers I linked to (above) for more details.
Two part question:
I have setup my website to use Facebook Connect for logging in. In the restricted area, I check if there is a cookie set with the name, "fbs_" under my domain name. However, I do not understand how this cookie gets set under my domain name. Does anyone know what happens with FB.Init call in this regard? (I have not used cross domain HTML file in my implementation).
Secondly, I am interested in implementing an Android setup that uses this web setup for data. Because these cookies look to be setup by the Javascript, I am not able to access these login cookies (fbs_ under mydomain.com) when I try with Cookie Manager. Is there a way I can implement this? Does WebKit help me in this regard?
Thank you for your time and responses.
The cookie is set under your domain as the JavaScript is executed there, and the FB code wants you to have access to the cookie data so you can use it to call the Graph API (or whatever you need to do with it). You should certainly be seeing this cookie set if logging in with Connect - how are you trying to access it? Is the Cookie Manager you mentioned a browser plugin?
I have a java applet that needs to do http requests to the server. A quick experiment showed that the session id cookies from the browser is not sent along, so i'll have to set it manually.
Currently, I see 2 possible solutions:
somehow get hold of the cookie data from within the applet
pass the cookie information into the applet's contructor via javascript
I'd prefer the first solution, but i wasn't able to find a working solution for that. all information i found (mostly netscape.javascript.JSObject) were outdated (my 1.5 VM does not have this class)
Any great ideas or resources i have not yet found?
Are you sure your JVM doesn't contain this class? You should look in $JAVA_HOME/lib/plugin.jar. I found it in my 1.5.0_14 installation.
If you are generating the page dynamically, you don't necessarily need to use JavaScript to communicate the session ID. As long as you know it server-side, you can place it into an applet parameter tag in the generated HTML which contains the <applet> tag.
Nowadays all browsers are supporting httponly cookies.If cookies are consciously set in server as 'httponly' in appropriate response headers,applets may not be able to access it.
By default tomcat will create a session cookie for the current domain.
If you are on www.example.com, your cookie will be created for www.example.com (will only work on www.example.com). Whereas for example.com it will be created for .example.com (desired behaviour, will work on any subdomain of example.com as well as example.com itself).
I've seen a few Tomcat valves which seem to intercept the creation of session cookies and create a replacement cookie with the correct .example.com domain, however none of them seem to work flawlessly and they all appear to leave the existing cookie and just create a new one. This means that two JSESSIONID cookies are being sent with each request.
I was wondering if anybody has a definitive solution to this problem.
This is apparently supported via a configuration setting in 6.0.27 and onwards:
Configuration is done by editing
META-INF/context.xml
<Context
sessionCookiePath="/something"
sessionCookieDomain=".domain.tld" />
https://issues.apache.org/bugzilla/show_bug.cgi?id=48379
I have just gone through all of this looking for a simple solution. I started looking at it from the tomcat perspective first.
Tomcat does not give direct access to configuring the domain cookie for the session, and I definitely did not want to custom patch tomcat to fix that problem as shown in some other posts.
Valves in tomcat also seems to be a problem solution due to the limitations on accessing headers & cookies built into the Servlet specification. They also fail completely if the http response is commited before it gets passed to your valve.
Since we proxy our requests through Apache, I then moved onto how to use apache to fix the problem instead.
I first tried the mod_proxy directive ProxyPassReverseCookieDomain, but it does not work for JSESSIONID cookies because tomcat does not set the domain attribute and ProxyPassReverseCookieDomain cannot work without some sort of domain being part of the cookie.
I also came across a hack using ProxyPassReverseCookiePath where they were rewriting the path to add a domain attribute to the cookie, but that felt way to messy for a production site.
I finally got it to work by rewriting the response headers using the mod_headers module in apache as mentioned by Dave above.
I have added the following line inside the virtual host definition:
Header edit Set-Cookie "(JSESSIONID\s?=[^;,]+?)((?:;\s?(?:(?i)Comment|Max-Age|Path|Version|Secure)[^;,]*?)*)(;\s?(?:(?i)Domain\s?=)[^;,]+?)?((?:;\s?(?:(?i)Comment|Max-Age|Path|Version|Secure)[^;,]*?)*)(,|$)" "$1$2; Domain=.example.com$4$5"
The above should all be a single line in the config. It will replace any JSESSIONID cookies domain attribute with ".example.com". If a JSESSIONID cookie does not contain a domain attribute, then the pattern will add one with a value of ".example.com". As a bonus, this solution does not suffer from the double JSESSION cookies problem of the valves.
The pattern should work with multiple cookies in the Set-Cookie header without affecting the other cookies in the header. It should also be modifiable to work with other cookies by changing JSESSIONID in the first part of the pattern to what ever cookie name you desire.
I am not reg-ex power user, so I am sure there are a couple of optimisations that could be made to the pattern, but it seems to be working for us so far.
I will update this post if I find any bugs with the pattern. Hopefully this will stop a few of you from having to go through the last couple of days worth of frustrations as I did.
As a session (and its Id) is basically considered of value only for the issueing application, you may rather look for setting an additional cookie. Have a look at Tomcats SingleSignOnValve, providing the extra-Cookie JSESSIONIDSSO (note the ...SSO) for the server path "/" instead of "/applicationName" (as JSESSIONID cookies are usually set).
With such a Valve you may implement any interprocess communication you need in order to synchronize any state between different servers, virtual hosts or webapps on any number of tomcats/webservers/whatever.
Another reason why you cannot use tomcats session cookie for your own purposes is, that multiple webapps on the same host have different session ids. E.g. there are different cookies for "/webapp1" and "/webapp2". If you provide "/webapp1"'s cookie to "/webapp2", this wouldn't find the session you referenced, invalidate your session+cookie and set its own new one. You'd have to rewrite all of tomcats session handling to accept external session id values (bad idea securitywise) or to share a certain state among applications.
Session handling should be considered the containers (tomcats) business. Whatever else you need you should add without interfering with what the container believes is necessary to do.
I've run into this at $DAYJOB. In my case I wanted to implement SSL signon then redirect to a non SSL page. The core problem in tomcat is the method (from memory) SessionManager.configureSessionCookie which hard codes all the variables you would like to get access to.
I came up with a few ideas, including a particularly egregious hack using mod_headers in apache to rewrite the cookie based on regex substitution.
The definative way to solve this would be to submit a patch to the tomcat developers that adds configurable parameters to the SessionManager class.
The valve techniques do not seem to be 100% perfect. If you dare to modify Tomcat itself:
catalina.jar contains the following class: org.apache.catalina.connector.Request
The Request has a method:
configureSessionCookie(Cookie cookie)
For our environment it was best to just hardcode it, but you could do more fancy logic:
cookie.setDomain(".xyz.com");
Seems to work perfectly. Would be nice if this was configurable in tomcat.