XSS VULNERABILITY FOR XML -- response.getWriter().write(xml.toString()); - java

I need to fix a issue for xss vulnerability. the code segment is below.
StringBuffer xml = new StringBuffer();
xml.append("<?xml version=\"1.0\"?>");
xml.append("<parent>");
xml.append("<child>");
for(int cntr=0; cntr < dataList.size(); cntr++){
AAAAA obj = (AAAAA) dataList.get(cntr);
if(obj.getStatus().equals(Constants.ACTIVE)){
xml.append("<accountNumber>");
xml.append(obj.getAccountNumber());
xml.append("</accountNumber>");
xml.append("<partnerName>");
xml.append(obj.getPartnerName());
xml.append("</partnerName>");
xml.append("<accountType>");
xml.append(obj.getAccountType());
xml.append("</accountType>");
xml.append("<priority>");
xml.append(obj.getPriority());
xml.append("</priority>");
}
}
xml.append("</child>");
xml.append("</parent>");
response.getWriter().write(xml.toString());
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
The issue is at the line having the syntax response.getWriter().write(xml.toString()); It says that it is vulnerable for xss attack. I have done sufficient home work and also installed ESAPI 2.0. but I donot know how to implement the solutions.
Please suggest a solution.

You should always escape any text and attribute nodes you insert into an XML document, so I would expect to see
xml.append("<accountType>");
xml.append(escape(obj.getAccountType()));
xml.append("</accountType>");
where escape() looks after characters that need special treatment, eg. "<", "&", "]]>", and surrogate pairs.
Better still, don't construct XML by string concatenation. Use a serialization library that allows you to write
out.startElement("accountType");
out.text(obj.getAccountType());
out.endElement();
(I use a Saxon serializer with the StAX XMLStreamWriter interface when I need to do this, but there are plenty of alternatives available.)

As I can understand:
AAAAA obj = (AAAAA) dataList.get(cntr);
here you have got some data from external source.
Then you've got to validate this data. Otherwise anyone can put any data there, that would cause the destruction on client side (cookies will be stolened for example).

ANSWER-- the code using the ESAPI is below.
xml.append(ESAPI.encoder().encodeForXML(desc));
It will escape the data in the variable 'desc'. By the implementation of this, the content in the variable 'desc' will be readed as data not executable code and hence the data will not get executed in the browser on the response of the back end java code.

Related

Java XSS Sanitization for nested HTML elements

I am using JSoup library in Java to sanitize input to prevent XSS attacks. It works well for simple inputs like alert('vulnerable').
Example:
String data = "<script>alert('vulnerable')</script>";
data = Jsoup.clean(data, , Whitelist.none());
data = StringEscapeUtils.unescapeHtml4(data); //StringEscapeUtils from apache-commons lib
System.out.println(data);
Output: ""
However, if I tweak the input to the following, JSoup cannot sanitize the input.
String data = "<<b>script>alert('vulnerable');<</b>/script>";
data = Jsoup.clean(data, , Whitelist.none());
data = StringEscapeUtils.unescapeHtml4(data);
System.out.println(data);
Output: <script>alert('vulnerable');</script>
This output obviously still prone to XSS attacks. Is there a way to fully sanitize the input so that all HTML tags is removed from input?
Not sure if this is the best solution, but a temporary workaround would be parsing the raw text into a Doc and then clean the combined text of the Doc element and all its children:
String unsafe = "<<b>script>alert('vulnerable');<</b>/script>";
Document doc = Jsoup.parse(unsafe);
String safe = Jsoup.clean(doc.text(), Whitelist.none());
System.out.println(safe);
Wait for someone else to come up with the best solution.
The problem is that you are unescaping the safe HTML that jsoup has made. The output of the Cleaner is HTML. The none safelist passes no tags, only the textnodes, as HTML.
So the input:
<<b>script>alert('vulnerable');<</b>/script>
Through the Cleaner returns:
<script>alert('vulnerable');</script>
which is perfectly safe for presenting as HTML. See https://try.jsoup.org/~hfn2nvIglfl099_dVxLQEPxekqg
Just don't include the unescape line.

Prevent xml escaping in Restful (JAXRS)

I have a restful service(jersey) that returns a url with request parameters in one of the tags. Example :
<url>http://abc:9080/testMe.jsp?req1=a&req2=b</url>
(It's part of the response)
When I get the response, I get as below ('&' becomes '& a m p;', without any space. I added space to avoid escaping here):
<url>http://abc:9080/testMe.jsp?req1=a&req2=b</url>
I looked up in google and found many ways to do it in jaxb but nothing in Restful (JAXRS). Also, I tried a lame solution of adding backslash but with no success.
How can I prevent it from happening in java 1.6?
There is nothing you should change, since this is like XML works: & is a special character in XML and any & contained in text is escaped as &
Your expected result ...=a&req2=b... would not be a well-formed XML document, whereas the result returned by Jersey is well-formed.
When you want to access the url value in the response document, you will need to parse the response with a XML parser (e.g. into a DOM document) and the parsed document will have the url value as you expect.

how can I clean and sanitize a url submitted by a user for redisplay in java?

I want a user to be able to submit a url, and then display that url to other users as a link.
If I naively redisplay what the user submitted, I leave myself open to urls like
http://somesite.com' ><script>[any javacscript in here]</script>
that when I redisplay it to other users will do something nasty, or at least something that makes me look unprofessional for not preventing it.
Is there a library, preferably in java, that will clean a url so that it retains all valid urls but weeds out any exploits/tomfoolery?
Thanks!
URLs having ' in are perfectly valid. If you are outputting them to an HTML document without escaping, then the problem lies in your lack of HTML-escaping, not in the input checking. You need to ensure that you are calling an HTML encoding method every time you output any variable text (including URLs) into an HTML document.
Java does not have a built-in HTML encoder (poor show!) but most web libraries do (take your pick, or write it yourself with a few string replaces). If you use JSTL tags, you get escapeXml to do it for free by default:
ok
Whilst your main problem is HTML-escaping, it is still potentially beneficial to validate that an input URL is valid to catch mistakes - you can do that by parsing it with new URL(...) and seeing if you get a MalformedURLException.
You should also check that the URL begins with a known-good protocol such as http:// or https://. This will prevent anyone using dangerous URL protocols like javascript: which can lead to cross-site-scripting as easily as HTML-injection can.
I think what you are looking for is output encoding. Have a look at OWASP ESAPI which is tried and tested way to perform encoding in Java.
Also, just a suggestion, if you want to check if a user is submitting malicious URL, you can check that against Google malware database. You can use SafeBrowing API for that.
You can use apache validator URLValidator
UrlValidator urlValidator = new UrlValidator(schemes);
if (urlValidator.isValid("http://somesite.com")) {
//valid
}

sensitive data leakage from -- response.getWriter().write(xml.toString()); via web page

xml.append("<alertDesc>");
xml.append(desc);
xml.append("</alertDesc>");
response.getWriter().write(xml.toString());
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
xml is a StringBuffer object.
I have this piece of code and there is some leakage of sensitive data from the syntax response.getWriter().write(xml.toString());. I don't have any idea of this thing.
Can any one tell me something about this? This issue is been reported by a code audit tool.
Its a wild guess, but did you forget to close a variable?
use validator and escaping techniches from ESAPI to wrap the desc field It will help!!!!!

send arabic SMS on mobile in java

in my application there is both arabic and english language suport but i am facing a problem when the mobile receive arabic SMS it is displaied as ??? ???? (question marks) knowing that the monbile i am using for testing supports arabic and all the arabic in the application is working fine the problem is only when an arabic SMS is received by my mobile.
String ff = new String(smsContent.getBytes("UTF-8"), "UTF-8");
StringWriter stringBuffer = new StringWriter();
PrintWriter pOut = new PrintWriter(stringBuffer);
pOut.print("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
pOut.print("<!DOCTYPE MESSAGE SYSTEM \"http://127.0.0.1/psms/dtd/messagev12.dtd\" >");
pOut.print("<MESSAGE VER=\"1.2\"><USER USERNAME=\""+userName+"\" PASSWORD=\""+password+"\"/>");
pOut.print("<SMS UDH=\"0\" CODING=\"1\" TEXT=\""+ff+"\" PROPERTY=\"0\" ID=\"2\">");
pOut.print("<ADDRESS FROM=\""+fromNo+"\" TO=\""+toNO+"\" SEQ=\"1\" TAG=\"\" />");
pOut.print("</SMS>");
pOut.print("</MESSAGE>");
pOut.flush();
pOut.close();
URL url = new URL("url");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
out.write("data="+message+"&action=send");
out.flush();
SMS in english working file in my application.
First, new String(smsContent.getBytes("UTF-8"), "UTF-8") is a redundant roundtrip, equivalent to smsContent. First you encode the string as bytes via UTF-8, and then immediately decode it back from the bytes again.
Second, your method of puzzling together XML is completely broken. You can't just concatenate strings and hope to end up with well-formed XML. Just for example think about what happens if someone tries to send a "? Use an XML library.
Third, you're implicitly using the platform default encoding for your OutputStreamWriter instead of explicitly specifying one, which means your code only works on those machines which randomly happen to have the correct encoding as default. I'm guessing yours does not.
Fourth, your method of puzzling together POST parameters is broken. You haven't specified what the variable message is. I'm guessing it's the complete XML document, but then you're trying to send it as a POST parameter to some kind of HTTP service, in which case it needs to be escaped/url-encoded. Just for example, what happens if someone tries to send the message &data=<whatever>&? Please clarify.
See also Using java.net.URLConnection to fire and handle HTTP requests
Fifth, since you're sending to some HTTP service, there's probably some documentation for that service what encoding to send or how to specify it, possibly with a HTTP header (Probably "Content-type: application/x-www-form-urlencoded; charset=UTF-8"?). Point us to the documentation if you can't figure it out yourself.
Edit: Found the documentation: http://www.google.se/search?q=valuefirst+pace
It pretty clearly states that you need to url encode the XML document, so that's probably what you're missing, in which case the encoding for the OutputStreamWriter won't matter as long as it's ASCII-compatible.
However, the documentation does not specify which character encoding to use for url-encoding, which is pretty weak. UTF-8 is the most likely though.
From what I've read on some internet pages, SMS in arabic languages (and others too) are encoded with UCS-2 and not UTF-8. Changing the encoding is worth a try.
You are using your platform's default encoding for the request data, which may very well differ from UTF-8. Try specifying UTF-8 in the OutputStreamWriter:
... new OutputStreamWriter(connection.getOutputStream(), "UTF-8") ...
Another issue is of course that your hand-made XML document will fail as soon as any of your parameters contain characters, which have to be escaped in XML, but that's a different story. Why don't you use an XML library instead?
Just an additional information: The documentation Christoffer points to also explains that the request example you are using is only suitable for text messages with characters in the standard SMS character set. For Unicode character support, you have to use a different request.

Categories

Resources