I'm trying fix a site vulnerability, it is "Improper Input Handling" attack raised by WhiteHat. Let's say my website is www.mywebsite.com and there is hacker's website www.hacker.com
whenever there is a request send to www.mywebsite.com with modified "Host" header point to www.hacker.com, my site will create a redirect to www.mywebsite.com along with whatever the url it was. To fix this I tried below tomcat virtual host configuration but still it's redirecting to other website.
<Host name="defaultlocalhost" appbase="whatever">
<!-- allow addresses to these host -->
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow=".*\.mywebsite1\.com|.*\.mywebsite2\.com"/>
</Host>
So, my question is, is it the right approach to prevent this host header attack ? If yes, what I did wrong that still not working? (The ultimate goal is, if it is not the legit Host that been passed in, the request should be discard/ignored/return 404 but not redirect with 302)
Related
I have a web application which is hosted at https://example.com. I would like to share a session cookie between the main domain https://example.com and sub-domain https://www.example.com. Thus, there should be no need for a user to re-login if they switch from one domain to another. How do I achieve this in springboot 2.2.6?
This is what I have tried:
I went to application.properties and set server.servlet.session.cookie.domain=.example.com
Now, this does not help. I get an error:
java.lang.IllegalArgumentException: An invalid domain [.example.com] was specified for this cookie
at org.apache.tomcat.util.http.Rfc6265CookieProcessor.validateDomain(Rfc6265CookieProcessor.java:210) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
at org.apache.tomcat.util.http.Rfc6265CookieProcessor.generateHeader(Rfc6265CookieProcessor.java:145) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
at org.apache.catalina.connector.Response.generateCookieString(Response.java:973) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
If I set server.servlet.session.cookie.domain=example.com, then the cookie is not visible for http://www.example.com and if I set server.servlet.session.cookie.domain=www.example.com, then the cookie is not visible for http://example.com
I have read discussions about Rfc6265CookieProcessor and LegacyCookieProcessor, but I don't know the right way to fix this issue.
Springboot 2.2.6 uses tomcat version 9.0.*
So, how do I fix this issue?
EDIT:
I was trying the above changes on localhost only and not on production. Instead of accessing http://www.example.com, I was doing https://www.localhost and instead of accessing http://example.com, I was doing http://localhost
The right value is:
server.servlet.session.cookie.domain=example.com
What I was trying was that I was making changes on localhost and they were not working for me. I was modifying the values in chrome console manually and expecting to see cookies set on https://localhost with domain localhost to be visible in another tab for domain https://www.localhost and that was not happening.
I read the answer here: Share cookie between subdomain and domain and #Cesc 's comment on that answer which was :
I am not sure where to put this so I am choosing the comments of the
accepted answer. It took long time and failed experiments to prove the
above on my localhost, until it occurred to me that I should call the
localhost with a dot in the name. Like "localhost.com" or something
like that. Then all the "set cookies" behaviours started following the
explanations written here in this answer. Hoping this might help
somebody.
So, I tried my changes on production directly and they worked fine. I am still not able to get it to work on localhost. The way I access my website on localhost is:
https://localhost and https://www.localhost. Based on #Cesc 's comment, I probably need to access the website on localhost as https://www.localhost.com or https://localhost.com and then it will work. But, I have not tried that.
Rather than testing with 'localhost' on your dev machine, try using your machine's fully-qualified host name. I've had a similar challenge with testing authentication against our single-signon platform.
I'm facing a difficult setup where I have to configure single sign on, based on the logged in used on my tomcat application.
I already took some steps which allow me to login via single sign on directly on my tomcat application by using waffle.
I have 1 server where I have a tomcat running and a IIS running (but this IIS will move to another server in the same domain in the future).
I have the Tomcat running on port 8205 and the IIS configure to accept url's from authpoc.company.com. IIS does a redirect to localhost:8025 via URL Rewrite.
My web.xml from IIS
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:8205/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
What works
When opening the application directly on localhost:8205 on the server. I get a nice single sign on based on my domain user.
When opening the application directly on the ip of the server. 192.168.1.1:8205. I can log in but single sign on does not work anymore. This I don't understand. (edit: solved, this is a setting in Internet explorer, see SSO waffle asking username and password for more information)
What doesn't work
When redirecting from IIS, I don't get to login into my tomcat application. I have windows authentication enabled, with Negotiate and NTML enabled (in this sequence).
I read a lot on the internet but I can't find anyone with this particular setup. I don't really have the impression I'm doing something exotic.
One possiblity is that I should connect IIS via AJP instead of a much simpeler URL rewrite.
any help is welcome! Thanks
I got an answer on the google groups saying this is not possible because of the reverse proxy counting as a hop.
https://groups.google.com/forum/#!topic/waffle-users/VCaawJMD0Mw
I'm going to try another approach
I am using JBoss-4.2.3.GA and have configured IIS to Integrated Windows Authentication and have disabled anonymous access.
I created a JSP page with the following code -
<% out.print(request.getHeader("Proxy-Remote-User")); %>
Which displays null and doesn't get the User Name.
But if I try it using ASP with -
Request.ServerVariables("AUTH_USER")
It gives me the correct User Name.
I tried other methods in request object like -
out.print(request.getHeader("AUTH_USER"));
out.print(request.getUserPrincipal());
out.print(request.getHeaderNames());
out.print(request.getRemoteUser());
But all of them gave null values.
The list of Headers in the request object that I am getting are -
connection, accept, accept-encoding, accept-language, authorization, cookie, host, user-agent, tomcatworkeridx6a6b0000, content-length.
I also looked into the server.xml in the JBoss Directory and found enableLookups="false"
I changed it to enableLookups="true" but it automatically got modified to enableLookups="false" on server restart. Is it necessary to have enableLookups as true? If so, how to stop it from being set to false automatically when I restart the JBoss server?
How can I get the remote user name from the request object?
Thanks!
Try setting tomcatAuthentication="false" on your AJP connector object as mentioned here. Your Connector in server.xml should look something like the following:
<Connector port="8009" address="${jboss.bind.address}"
emptySessionPath="true" enableLookups="false" redirectPort="8443"
protocol="AJP/1.3" connectionTimeout="600000" maxThreads="200"
tomcatAuthentication="false" />
(I'm not 100% certain that applies to the AS as well as the stand-alone web server, but it seems worth a shot)
As noted in the link above the enableLookups property merely controls whether request.getRemoteHost() actually performs a DNS query or not and, consequently, has no bearing on getting the REMOTE_USER header set properly
For JBoss I had to write an asp and get the User Name by Request.ServerVariables("REMOTE_USER") and then pass it to my JSP
I'm trying to create a virtualhost in Tomcat 5.5. Up till now I've created the Host entry
<Host name="www.nikoslianeris.gr" appBase="test"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="test" prefix="mydoamin_access_log." suffix=".txt"
pattern="combined" resolveHosts="false"/>
</Host>
and everything is ok with that. The problem is that when I put my app in the appbase directory nothing happens. I mean, I can see from the admin console the new virtual host bat when I type the url nothing happens. I don't know what the problem might be! I found many tutorials on the subject and did what they said but nothing happens!
just brainstorming, but have you mapped www.nikoslianeris.gr to your local machine in your hosts file or a local DNS? ie any request to that domain should result in the request being sent to your machine, then the request gets sent to tomcat, and only then does the virtual host settings above kick in.
In theory you can test if this is the case using ping or traceroute on that domain, or by telnetting to your local machine on the Tomcat port and writing a sample HTTP request and also specify the "Host:www.nikoslianeris.gr" in the HTTP header. In theory.
On my site wemanageloans.com, many of the users are getting the following error when they try to login with the correct credentials:
HTTP Status 408 - The time allowed for the login process has been exceeded. If you wish to continue you must either click back twice and re-click the link you requested or close and re-open your browser
This happens only if they try to login from URL:
http://www.wemanageloans.com
I have set up domain forwarding to URL:
http://59.176.19.181:8080
This error does not happen if the user tries to access the above IP address based URL directly.
Also, while this error occurs all the time for some users, it does happen intermittently to some users.
Please advise as to what could be wrong with the domain forwarding and what I may need to configure on my side.
I am using Tomcat 6' authentication using j_security_check.
When I visited the site I've seen that the session cookie was not immediately set - not even after the first login attempt.
I guess that there's something wrong with the start of a session.
As "forwarding" is done through a frame that masks your site, I'd suggest to stop this: it obfuscates quite a bit of what happens. Either get correct DNS resolution, use mod_jk or similar to serve tomcat content through apache or just redirect people to directly use the IP. This will most likely get rid of your problems (I've never seen them in this scenario). In case of using the IP directly it results in an ugly URL, so correct DNS resolution should be what you aim for.
Edit: Don't know if you already do this: Keep in mind that - using j_security_check - you can't just provide the login form to the user but need to rely on tomcat to present it (AFAIK). Therefor your page http://59.176.19.181:8080/personalcredit/loans.htm (which is the first page shown) is not supposed to have the login form on it, instead the page has to be declared as protected, so that tomcat by itself provides the configured login page to the user. If loans.htm was not declared protected, there was no reason for tomcat to start a new session which would explain the observed behaviour.
It wouldn't explain the nondeterminism though.
Could be caching related. Try sending a header like:
Cache-Control: no-cache,no-store,must-revalidate
Pragma: no-cache
Just to rule this option out...
Anyways 408 is about timeouts, could it be that your server takes more time
to route those requests? Unlikely, but possbile though.
Another approach would be to set your tomcat server.xml to listen to port 80,
just to make sure that using port 8080 is not causing the problem...
server.xml would need to look sthing like:
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443" />
hth
I fixed this issue by adding an Interval to login.html and login-failure.html
setInterval(function(){
location.reload(true);
},5*60*1000);
The login.html and login-failure.html are the same. Except login-failure.html contained a text "Username or password is incorrect"
I seem to have found a very simple solution
<meta http-equiv="Cache-Control" content="no-store,no-cache,must-revalidate"/>
<meta http-equiv="Pragma" content="no-cache"/>
<meta http-equiv="Expires" content="-1"/>
Thanks to Greg
http://readlist.com/lists/tomcat.apache.org/users/7/35987.html