Tomcat 7 is ignoring cookies? - java

I'm trying to upgrade from Tomcat 5.5 to Tomcat 7, and almost everything is working -- I just have some cookies that are getting through on Tomcat 5.5, but disappearing on Tomcat 7. That is, Firebug confirms that the cookies are being sent in both cases, but on Tomcat 5.5 they show up in a request.getCookies() call, and in Tomcat 7 they don't. Some cookies still show up (JSESSIONID, for example), but a couple are missing.
This is the same application running on the same server, port, etc, I just shutdown Tomcat 5.5, startup 7, and the cookies no longer get through.
If it's relevant, both Tomcat instances are behind an Apache proxy running on a different server. It doesn't seem like it should be relevant, though, since Apache is clearly able to pass the cookies to Tomcat 5.5.
My guess is it's a security feature of some sort, though I haven't been able to figure out what it would be. The missing cookies are for domain .domain.org, while the cookies that are getting through (like JSESSIONID) are for host subdomain.domain.org (bolded text is just an example, obviously).
I tried setting useHttpOnly to false and crossContext to true in the context, in case it had something to do with one of those, but it didn't help. Besides those two settings, are there any other new features in Tomcat 7 (or Tomcat 6, for that matter) that could lead to it leaving out cookies? And if so, is there a handy workaround?
EDIT: I forgot to mention that it probably doesn't have anything to do with the cookie path -- the cookies that don't work have a path of "/", and the cookies that do work have variously "/", "/application", and "/application/".

I figured it out! The problem was colons in the cookie names. Apparently the HTTP specification doesn't allow colons that aren't quoted. Tomcat started enforcing this in 5.5.26 -- coincidentally, I had been using 5.5.25.
It doesn't solve my problem -- these cookies are set by third-party software -- but it does answer the question!
If you have colons in your cookie names, either they need to be quoted (like so ":") or you need to use Tomcat 5.5.25 or older. I may try to configure my Apache proxy to modify the cookies on their way through... if that works, I'll update this answer.
There is some more detail about this in the comments on this bug report.

I might be late to a party, but I had a similar problem that required a much different solution.
The problem was in login data stored in cookies and then having the keys hard-coded in a file to confirm who is who. Due to WAR packaging, the paths got lost in a transfer, and the only thing I had to do was to correct the paths to right JSON files on a server.
Therefore, the issue was not in Tomcat but in a way the things got transferred and calls to those things.
Spent half of a day to locate the issue (I thought that there was some setting to be done in Tomcat), but then it was very simple once I realized that paths to a JSON were off.

Related

Tomcat 9 Application causing 502 error after logging in

I manage a few Tomcat 9 applications that are run on a remote server that also use IIS 8.5. Each site has three environments (DEV, TEST, and PROD). All of the environments are the same but on different servers. Their databases (Oracle DB) are also on separate remote servers. I do not use any other third party frameworks for the sites (such as Maven or Gradle).
One of my applications had an issue where an attacker could access the web.xml through a Multiple Directory Traversal Vulnerability. Some brief information can be found here: https://www.securityfocus.com/bid/63052/exploit
However, I discovered on the DEV and TEST (I thought PROD as well) that the filter we put in place was actually causing the site to not work correctly. You'd put in your user and password and click login and nothing would happen. I seemed to have fixed it on the DEV and TEST environment by fixing the regular expression that my code was testing the URI against. Code:
final String REGEX_INCLUDED = ".*\\/WEB-INF\\/web.xml.jsf.*";
...
if (Pattern.matches(REGEX_INCLUDED, URI)) {
log.debug("SecurityFilter redirect");
resp.sendRedirect("/errors/403.html"); // /login.jsf OR /index.html
} else
chain.doFilter(request, response);
I deployed the new war onto PROD, entered my user and password and it would load. The site redirects to the homepage after login, BUT it doesn't actually load if that makes sense. The response is a generic 502 error (shown below) but the URL does, in fact, say /home.jsp where it should respond with the homepage.
502 Error
I've checked the catalina log and I've not found a stack trace or any sign of an error being output. No other logs are useful either in showing what the issue is. I've tried just clearing my cache and retrying, using a different browser, restarting the tomcat service, restarting the site in IIS and nothing.
If there is something I'm missing that you wish to see let me know. BTW, I've tried removing the filter that blocks access to the web.xml just to make sure it wasn't the issue and both with and without the filter, it results in the 502 error.
Thanks in advance for any help.
Answering my own question: I had looked around everywhere and only after posting I found a related post:
502 proxy error on deployment
Their answer helped. The difference between my PROD environment and my DEV/TEST environments is that PROD is on a Proxy. I went to IIS on the server and found the server farm that the site used. I then clicked on the Proxy option and changed my timeout from 30 seconds to 60 seconds. Looks like my proxy was timing out. Hope this helps someone in the future.

How to switch with another application when redeploying a WAR?

Sorry if this question was asked before, if it was, I didn't find it.
I'm using GlassFish 4.
When I need to redeploy an application (for fixing a bug for exemple), its URL will return temporarily a 404 NOT FOUND error until the application is fully redeployed.
My question is: do you know a way to redirect the URL to another application or a web page ("Application not available for the moment...") during the time the URL is inaccessible?
I heard of load balancer but it's between 2 servers (which I don't have).
Thank you.
You can use rolling updates to update an application without any downtime, by using the :version suffix. For full information on how to do it, see the blog post at http://blog.payara.fish/payara-server-rolling-upgrades.

Forbidden You don't have permission to access on searching a special character

I am supporting a java application which has a search bar which matches the keywords and gets the results from the cache.
The application runs in Tomcat and has a Apache web server too.
There is an issue while searching aaa' the special character ' is causing the problem and i get to
Forbidden
You don't have permission to access /xx/xx/xxxx.jsp
The search is fine in local setup with the abscence of Web Server. As i saw some posts suggesting the issue could be caused by Web server config.
What are the possibilities?
Your help is highly appreciated.
Thanks,
Nagaraja JB
Apache web-server's security configuration must be causing this. Look into the web server logs, you will find rule code/name which is triggered because of these sequence of characters.
Disabling rule is one of the options to make this work but not always a good idea.
The issue was not an issue it is a secutity constraint by the apache web server or FireWall rule to protect from cross site sctipting or sql injection using %27 (single quote). I used POST method instead of using GET method to send request. That is the solution for my case.

Flex file upload with HTTPS and JAAS?

We're trying to upload a file from a flex client to a Java EE app.
In a full HTTPS environment
Java EE server is JBoss 5
Using BlazeDS 'Custom' authentication (username and password are entered trhough a flex form)
Using BlazeDS per session authentication
In regular AMF calls, we can access user principal and use role mecanism.
However, in our upload servlet, we have no access to user principal.
request.getUserPrincipal() // returns null
How to fix this ?
A while ago a guy commented on a blog post of mine that https + flex + firefox doesn't work:
have you tried uploading a file in firefox via https? Well, don’t bother, it can’t be done! Adobe blames it on firefox and puts their head in the sand. Read the teeth gnashing and ridiculous claims of Adobe here:
http://bugs.adobe.com/jira/browse/FP-201
Ultimately they threw up their hands and said it couldn’t be fixed, and, although said ‘We understand that this is a serious issue and are committed to resolving it’ suggested that either you:
1) Send the file to your server in a different way
2) Find another form of authentication
This may no longer be the case - register and see if the linked bug is still unresolved.
Also - this might not be your exact issue (at least not yet) - I'm just giving pointers.
From your post, and since I haven't used BlazeDS, I can't tell whether you're running into this issue specifically, but it sounds to me like you are --
Take a look at your server logs, or try using a Web debugger like Fiddler (you can tweak it to reveal HTTPS traffic in clear text), and you'll see that Flash blocks custom HTTP auth headers with FileReference.upload(). Why it does, I've no idea, but there's no workaround I know of, other than crafting something or your own manually.

Best way for allowing subdomain session cookies using Tomcat

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.

Categories

Resources