Showing posts with label struts. Show all posts
Showing posts with label struts. Show all posts

XSS in the HTTP Header's Accept Language when using Struts 1.2

1
At my work, we have a policy of using HP's WebInspect to scan our applications before they are allowed to go into production and I just got an interesting finding this week. The WebInspect scanner tried to perform a XSS (cross site scripting) attack by putting something into the HTTP header's Accept Language! Now, I'm not really sure how exploitable this is (perhaps some security expert can comment?) since all our traffic is via https, so there's really no way to inject some scripts into the http header unless the host machine making the request has been compromised?

This was the http request used....

GET /programmingPanda/someUrl.jsp HTTP/1.1
Accept: */*
Referer: https:///programmingPanda/someUrl
Accept-Language: "><script>alert('hi')</script>
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Host: www.programmingPandaHost.com
Pragma: no-cache
Connection: Keep-Alive
Cookie:
JSESSIONID=0021w1Z_9Fg27Vg1xhKHDgX1YLR:1244ioqb0;CustomCookie=WebInspect30127ZXC16B0
44F25944608B21BBFFEC74B3453YE540


and the end result was this....


<html xmlns:"http://www.w3.org/1999/xhtml" lang=""><script>alert('hi')</script>" xml:lang=""><script>alert('hi')</script>">


Anyways, I was tasked with checking this out. After some digging, I found that the html tag in our application was being generated by the struts taglib's html tag. According to the specifications, it seems that the lang attribute of the html tag has the following behaviour...


Renders a lang attribute with the locale stored in the user's session.
If not found in the session, the language from the Accept-Language HTTP header is used.
If still not found, the default language for the server is used.


So with the Accept-Language not being validated for special characters, we were getting XSS-ed!

The solution? In this case, we used a filter to provide a default locale into the user's session if non is detected to avoid using the Accept-Language in the HTTP header. This may not be the best or most correct solution, but it is one that fits our needs and timeline.


//provide some default locale and set it into the struts defined attribute, Globals.LOCALE_KEY
session.setAttribute(Globals.LOCALE_KEY, locale);

Map struts .action/.do to the URL root

0
To map the URL root to certain welcome file, we normally just specify the welcome-file in the web.xml like this


index.html
index.jsp



What this means is, if in a directory without specifying any file name, the web application will first look for index.html and then index.jsp.

Now add struts framework into the picture, default struts extension for 1 and 2 is *.do and *.action respectively.

There are 2 ways of making our application pointing to the special struts action.

#1: Meta redirect
You can keep index.html or index.jsp as welcome-file and what you need to do is put a meta refresh in these index files

Struts 1
meta equiv="refresh" content="0;URL=/homepage.do"


Struts 2
meta equiv="refresh" content="0;URL=/homepage.action"


But the downside of this is - whatever action name you use would appear on the browser. (i.e. www.mydomain.com always appear as www.mydomain.com/homepage.action even user types in www.mydomain.com)

#2: Change welcome-file and add dummy place holder file

The second way (or better way) of fixing the struts action mapping to the URL root is to update the welcome-file list.

Struts 1

homepage.do



Struts 2

homepage.action



And then in the WebContent Root, add a dummy file (e.g. in Struts 2 you need an empty file homepage.action)*This step is important, without the empty dummy file, it won't work, at least in Tomcat*

Now when you hit http://www.mydomain.com your application will hit the homepage.action directly without adding the homepage.action after your url.