Input special character in search string when handled at server side - javascript

I'm testing a project I'm working on. Here I've put a filter on server side(Java) to redirect the page to Error page whenever I encounter any HTML tag like regex(URL Encoded is also checked) in query string. As per my skill set, it's working fine. But I'm very much sure it's not the end. There must be a way to still enter the vector to execute XSS script.
Examples : <hello> redirects to error page
%3Chello%3E converts to <hello> and redirected to error page
%253Chello%253E converts to %3Chello%3E & page works fine as no HTML tag is found.

The approach you're trying is black-list approach which is to search for bad characters (IE <, >) and redirect to an error page and\or encode it. This is the wrong approach.
You should use a white list of permitted characters and redirect to an error page if the input contains any non-permitted characters. One way to enforce this approach is regular expressions: ^[a-zA-Z0-9]*$ or ^[\s\w]*$. Adding both client validation and server validation would keep you safe and error-free (unless a hacker tries to bypass the client validation in which in this case the server validation would stop him).
If you try to guess the attacker's method you are destined to fail.
The right way to encode user originated input to prevent XSS is HTML Encoding, not URL encoding (not %3Chello%3E, but >hello<).
If you encode the user input you don't have to redirect the user to an error page as the examples you gave and the ones that I gave are harmless
Having said that, here is an example of XSS without < and >:
Let's say a page receives a picture file name and displays it, and does not encode the quote character:
https://contoso.com/displaypic?source=111.jpg
<img src="111.jpg"></img>
If you access this URL, you have yourself XSS:
https://contoso.com/displaypic?source=a"+onerror="alert('XSS')
<img src="a" onerror="alert('XSS')"></img>

Related

Unescapping client data in C# to prevent XSS or other attack

To prevent web application input from XSS or any other attack, we would like to decode all the input coming from the client (browser).
To bypass the standard validation, bad guys encode the data. Example:
<IMG SRC=javascript:alert('XSS')>
That gets translated to
<IMG SRC=javascript:alert('XSS')>
In C#, we can use HttpUtility.HtmlDecode & HttpUtility.UrlDecode to decode the client input. But, it does not cover all the type of encoding. For example, following encoded values are not getting translated using above methods. However, all the browser decode and execute them properly. One can verify them at https://mothereff.in/html-entities as well.
<img src=x onerror="&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041">
It gets decoded to <img src=x onerror="javascript:alert('XSS')">
There are some more encoded text that does not get decoded using HtmlDecode method. In Java, https://github.com/unbescape/unbescape handles all such varieties.
Do we have a similar library in .Net or how do handle such scenarios?
Generally, you should not allow users to enter code into a text box.
Client side
Judging from the comments on your post, I'd simply add some client-side validation to prevent users from adding any sort of malicious inputs (such as verifying email fields contain emails) and then add the same validation techniques to your server.
Server side
As soon as you read a user's input in a model, you should validate and sanitise it before you do any further processing. Have a generic AntiXSS() class that can remove any malicious characters such as the <> symbols by checking myString.Contains("<") or myString.Contains(">") for example. If it does, remove that character. Validate your types. If you're checking the userEmail field, make sure it conforms to email syntax.
The general idea is that you can pass data to the client, but never trust any of the data that comes back from the client without first sanitising and cleansing everything.
I found the solution. HtmlUtility.HtmlDecode decodes the chars between ampersand '&' and semicolon ';'. However, the browsers do not bother about the suffixed ';'.
In my case, semicolon ';' was missing. I have written simple code to insert a semicolon before calling HtmlDecode method. Now, it's decoding properly as expected.

Do you have to sanitize input in JS if only used for internal check

I have a JS script on my page which checks document.referrer for a specific URL. If it exists then it changes a button on the page. I can't do it server side because of Varnish caching.
Do I need to sanitize document referrer and if so how?
I know you have to sanitize any user input server side or if you're printing out HTML from user input. Do you also need to do it if you're running checks on it?
If so will a basic function like encodeURIComponent suffice or do I need to create a bunch of manual escapes to strip characters?
if(document.referrer.contains('mywebsite.com/url')){
button.replaceWith(button2);
};

A potentially dangerous Request.QueryString -- How to prevent without turning off safety features

I am getting this message when I perform a post with some data encoded in the query string. I have browsed the web on this and all the solutions are about turning off the validation -- which seems backward to me. What I want to do is modify the query string so that it doesn't trigger the validation in the first place.
The query string is urlEncoded with this javascript:
var qs = 'i=' + id+ '&c=' + encodeURIComponent(c) + '&' + 'p=' + encodeURIComponent(p);
'Id' is just an integer, so the c and p parameters are the only ones likely to cause this, and they are both URIencoded.
What causes this error, and what, beyond uri encoding can I do to prevent the complaint?
I don't like turning off safety features. It is smart to wear a safety belt when you are driving.
This is a safety belt only for people that haven't passed their driving test. If output is correctly encoded, the "potentially dangerous" query string value is no longer dangerous.
For example, if the character " is output to HTML this should be encoded as ", or if the character ' is output to JavaScript then it should be encoded as \x27.
ASP.NET Request Validation only protects your code if you are not correctly encoding for output, and furthermore it only protects values that have been input via a website with Request Validation enabled. Anything input from any other sources (e.g. a shared database, another application or an external API) will not be validated by request validation. This is why I would code your application to handle correct output encoding instead. If stackoverflow.com blocked potentially dangerous input then it would not be possible for people to write code like this in their posts: <script>alert('example');</script>, but with proper output encoding, as you can see this is safe.
Check out my post on ASP.NET Security (A3-Cross-Site Scripting (XSS) section).
Also see the OWASP XSS Prevention Cheat Sheet.
You're right, most "fixes" for this tell you to turn off validation so it was kind of difficult to find something other than that. I think you're going to have to turn it off just for that request and then manually validate it. According to microsoft, you can disable it for a request like this:
Request.Unvalidated("userInput"); // Validation bypassed
Request.Unvalidated().Form["userInput"]; // Validation bypassed
If you disable request validation, you must manually check the unvalidated user input for potentially dangerous input
See this article: http://msdn.microsoft.com/en-us/library/hh882339(v=vs.110).aspx
Good Luck!
The ASP.NET team doesn't want you rely on 'RequestValidation' so it is ok to turn it off (it's a crutch that gives a false sense of security because it isn't always up to speed).
For info on why this ok and what you should do instead, watch this video starting at 11:10. I would actually recommend watching the whole video.

Encoded HTML Tags in Query String still causing 500 Error

Hoping this is a quick fix.
I'm sending a query string from an AngularJS application to a web API coded in C#. The string contains a "message" value which may or may not contain url-encoded HTML tags.
Here's a basic example:
msg = "<a>"
querystring = "/SERVERPATH/?id=1&msg=%3Ca%3E"
Sending the string above to my API results in a 500 Error and the "msg" value never actually reaches the server. On the other hand, adding a space before and after the "a" causes everything to work great.
msg = "< a >"
querystring = "/SERVERPATH/?id=1&msg=%3C%20a%20%3E"
Is there a special type of validation occurring that I don't know about, and is there a way to configure these rules myself?
This is probably web.config related, but I could be totally wrong about that. Any input would be greatly appreciated.
The error code 500 is for internal server error. It means your code do reach your web service. By your example (where on putting a space before and after 'a' makes everything work) I am pretty sure that request validation is failing at your web service. To understand request validation please visit this link.
A word of caution: Try not to disable request validation on your web service. Doing that poses a huge security threat.
You may consider a work around, where instead of using URLEncode you can use HTMLEncode for encoding the query string values (values only).

JavaScript and JQuery - Encoding HTML

I have a web page that has a textarea defined on it like so:
<textarea id="myTextArea" rows="6" cols="75"></textarea>
There is a chance that a user may enter single and double quotes in this field. For instance, I have been testing with the following string:
Just testin' using single and double "quotes". I'm hoping the end of this task is comin'.
Additionally, the user may enter HTML code, which I would prefer to prevent. Regardless, I am passing the contents of this textarea onto web service. I must encode the contents of the textarea in JavaScript before I can send it on. Currently, I'm trying the following:
var contents $('<div/>').text($("#myTextArea").val()).html();
alert(contents);
I was expecting contents to display
Just testin' using single and double "quotes". I'm hoping the end of this task is comin'.
Instead, the original string is printed out. Beyond just double-and-single quotes, there are a variety of entities to consider. Because of this, I was assuming there would be a way to encode HTML before passing it on. Can someone please tell me how to do this?
Thank you,
If you're sending to a web service, you'll presumably be URL-encoding these (as part of a POST, for instance, either via form submission of Ajax). That will handle any necessary escaping at your end. The service at the other end is responsible for interpreting the input string correctly. If the service doesn't accept HTML tags, it's the service's job to do the necessary entity encoding (or whatever other kind of encoding it wants).
If the service doesn't take responsibility for this, it's open to errors in the client and attacks by people with nefarious intent. So it's really the other end's problem.
By using:
var contents = $("<div/>").text($("#myTextArea").val()).text();
alert(contents);
You display the textual contents instead of the contents in html.

Categories

Resources