Showing posts with label XSS. Show all posts
Showing posts with label XSS. Show all posts

Wednesday, January 08, 2014

C# : Cross site scripting and quotes

Busy developing a web site (ASP.NET, C#, Windows Forms, .NET Framework 4) and I got some security gurus to help do some security / penetration testing.

The site has some forms where you enter user details into text boxes. This is stored in a DB. You can search for users and the results are displayed in a grid e.g. first name, last name, email, roles etc.

So if you entered some Javascript into the last name text box e.g.

script Alert ('XSS error'); /script

(insert your own angle brackets!)

this would be written to the DB and when the grid displayed the next tine, you would see the Alert - the dreaded XSS syndrome.

Microsoft has a library to handle this - the somewhat maligned AntiXSS.

This has methods for HTML encoding, CSS encoding, URL encoding, injection etc.

So e.g. you can use:

AntiXssEncoder.HtmlEncode(lastname, true);

If someone types:

 script Alert ('XSS error'); /script

as a last name, this is encoded as:
 
<script>Alert (‘XSS Error’);</script>


which is harmless.

Now that's all well and good but you will note from the above that the single quote "'" is also encoded.

So what happens when you have someone with a name of O'Reilly?

Bad stuff happens - that's what!

What is saved is:

O'Reilly

There are many Google hits around the fact that the library is actually too strict etc. etc.

What I do is after the encoding, is:

lastname.Replace("& # 3 9 ;''", "'");     // Remove the spaces

So it's back to the single quote.

 You could also use something like:

Sanitizer.GetSafeHtmlFragment (lastname);

which removes a few HTML elements like script - so in this case there's just an empty string.

And for injection e.g. LDAP, you can use:

Microsoft.Security.Application.Encoder..LdapFilterEncode("xyz");

Enjoy!




Wednesday, March 10, 2010

Preventing Cross-Site scripting in Java

You can read about XSS here: Cross-site scripting

Been trying to figure out how to disable it using html encoding and what Java libraries are available.

OWASP's site has an article on this: http://www.owasp.org/index.php/How_to_perform_HTML_entity_encoding_in_Java

To quote:

"Injection attacks rely on the fact that interpreters take data and execute it as commands. If an attacker can modify the data that's sent to an interpreter, they may be able to make it misbehave. One way to help prevent this from happening is to encode the attacker's data in such a way that the interpreter will not get confused. HTML entity encoding is just such an encoding mechanism for many interpreters."

There are two ways to encode the data viz. entity reference and numeric reference:

From Wikipedia:
http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references

An entity reference uses the "&" symbol:

& quot; (double) quotation mark
& amp; ampersand
& apos; apostrophe (= apostrophe-quote)
& lt; less-than sign
& gt; greater-than sign

A numeric character reference refers to a character by its Universal Character Set/Unicode code point, and uses the format

&#nnnn;
or

&#xhhhh;
where nnnn is the code point in decimal form, and hhhh is the code point in hexadecimal form

Although the OWASP article mentioned above talks about entity references, the code sample enclosed actually uses numeric entity encoding i.e.

<script></script>

encodes as:

&hash60;script&hash62;&hash60;&hash47;script&hash62;

where "hash" = the "#" character

Some further research around this issue leads to:
AntiXSS for Java which is a port to Java of the Microsoft Anti-Cross Site Scripting (AntiXSS) library for .NET applications

and to:
Open Web Application Security Project (OWASP)

which has a:
Enterprise Security API (ESAPI)

Click on the "Java EE" tab. There are two ways to invoke the functionality. One uses the classes directly:



import org.owasp.esapi.codecs.HTMLEntityCodec;

public static StringBuilder esapiCodecHtml (String s)
{
HTMLEntityCodec hec = new HTMLEntityCodec();
StringBuilder b = new StringBuilder(s.length());
char[] immune = { ',', '.', '-', '_', ' ' };
String returnStr = "";

String clean = ESAPI.encoder().canonicalize(s);
System.out.println ("Cleaned result is " + clean);

for (int i = 0; i < s.length(); i++)
{
char ch = s.charAt(i);
returnStr = hec.encodeCharacter(immune, ch);
b.append(returnStr);
}

return b;
}


Note: ESAPI canonicalizes input before validation to prevent bypassing filters with encoded attacks. Failure to canonicalize input is a very common mistake when implementing validation schemes. Canonicalization is automatic when using the ESAPI Validator.

and the other uses the wrapper:



import org.owasp.esapi.ESAPI;

public static String esapiEncodeForHTML (String s)
{
String returnStr = "";

String clean = ESAPI.encoder().canonicalize(s);
System.out.println ("Cleaned result is " + clean);
returnStr = ESAPI.encoder().encodeForHTML(s);

return returnStr;
}


They both convert <script></script> to andlt;scriptandgt;andlt;&hashx2f;scriptandgt;

where "and" is the "&" character.

Interestingly, this is a combination of both reference types.

Just to note: The example at the top converted the "/" to &hash47; whereas ESAPI converts it to &hashx2f; This is because one is decimal and one is hex!

Asides:

Refer to:

XSS (Cross Site Scripting) Prevention Cheat Sheet

Refer to my SO question:

Java - XSS - HTML encoding - Character entity reference vs. Numeric entity reference

Enjoy!