Here is a rookie question, if I have a textarea that doesn't submit anywhere...
<form onsubmit="return false;">
<textarea name="new_title_text" id="new_title_text"></textarea>
</form>
and I use jQuery to prepend the value of the textarea to a div...
var textValue = $('#new_title_text').val()
$('#myDiv').prepend('<div>' + textValue + '</div>');
Are there any security vulnerabilities with this? Can someone somehow inject JavaScript and preform XSS, CSRF or any other type of attack? I understand that once I submit the value to my server then it needs to be checked, but is there anything that can happen before submission?
Thanks in advanced!
Basically you can't trust any validation done client side as people can (pretty easily) bypass JavaScript validation.
Do your proper validation and sanitation on your server and leave the client side validation simply for the user experience and to not "bother" your server with clearly invalid data - such as empty fields where a value is required.
Unless you are letting your users submit some PHP code or JavaSctipt code to be executed elsewhere on your site you should be safe. Always remember NOT to trust any data coming in from users. Treat all incoming data as a potential threat and sanitize anything you deal with if you plan to use it later.
Can someone somehow inject JavaScript and preform XSS, CSRF or any other type of attack
Yes. You are injecting text into an HTML string without HTML-escaping, so any metacharacters in that string (< or &) will fail and may be vulnerable to injection attacks (eg <script>...).
The question is who is that someone? From your current code it doesn't appear possible for an external party to pre-fill the textarea, so it would have to be the user attacking themselves (not really a vulnerability).
So you either need to HTML-escape the string going into HTML, or, better, use DOM-style access methods like .text() and .attr() to set text content and attributes without using crude string markup generation. Or the creation shorthand:
$('#myDiv').prepend(
$('<div>', {text: $('#new_title_text').val()})
);
The basic idea is that yes, it's unsafe to use prepend with untrusted data. However the exploitability does depend on the scenario. If an attacker can craft a url that causes that script to run with an untrusted value, you definitely have an XSS problem. If however a user can only trigger this himself by entering unsafe data and clicking the button, it's more safe, but not quite. This is often called self-xss and is sometimes exploited together with clickjacking etc.
For more info on unsafe jquery functions see: http://erlend.oftedal.no/blog/?blogid=127
Related
I have to use some HTML tags in innerHTML. But it's giving some security issues. I can't use innerText etc because I have to show HTML content instead of plain text.
$(this).parent()[0].innerHTML = newInnerHTML;
What are the workarounds for this. or is there a way to resolve the vulnerabilities. I tried sanitizing the HTML but it didn't work. Please provide your suggestions.
Thank you.
I know you said you tried sanitizing it already, but maybe you were doing it wrong. If you need to put user input as an innerHTML string without a risk of xss, you can use a library like https://www.npmjs.com/package/xss-clean to sanitize only the user input. If the html content is hard coded, there isn't a risk of xss. The risk of using innerHTML only applies when a user can submit an HTML string to a server that could be visible to other users.
I got following 2 questions as:
1) How to protect from this kind of XSS Attacks?
https://www.example.com/index.php?javascript:alert('XSS')
If suppose for some reason, the query parameter is embedded in an image load event then it would be like this
<img src=x onload="javascript:alert('XSS')">
//And browser treats as
<img src=x onload="javascript:alert('XSS')">
I am already using PHP's htmlspecialchars() and Filtar_var() with URL Sanitization, but this kind of encoded XSS will easily get pass through these functions
How can we defend such Encoded XSS or neutralize any such attack?
2) Is it necessary for an XSS attack to get embedded in HTML Page, Javascript or CSS etc in order to get triggered? or there can be a way where XSS does not need to be embedded?
htmlspecialchars is a perfectly good defence against XSS when you are inserting user input into an HTML document.
It stops any HTML syntax in the user input from breaking out of where you intend for it to go and being treated as JavaScript.
Your problem has nothing to do with the fact the attack is encoded. The problem is that are are putting user input somewhere that JavaScript is expected (and onload attribute) so it is already being treated as JavaScript.
json_encode is the usual solution here (and then htmlspecialchars because the JavaScript is inside an HTML attribute).
However, that only works when you are taking user input and putting it into a script to be used as data. Here it seems that you are taking user input and just treating the whole thing as a JavaScript function.
If you do that then you are going to be vulnerable to XSS. You can mitigate it to some degree by implementing defenses against CSRF, but you almost certainly shouldn't be doing this in the first place.
I have a disagreement with a security auditor, whether a snippet of html/js is vulnerable to XSS or not.
In short this is it:
<html>
<form name="myform" action="page.php" method="post" onsubmit="return validate()">
<input name="field" type="text" size="50" />
<input type="submit" value="Submit" />
</form>
<script>
function validate()
{
var str=document.myform.field.value;
alert("Error in " + str);
return false
}
</script>
</html>
So, my auditor says that this can be vulnerable to DOM-based XSS, but has not yet given me an example.
I personally think that it is not, since because of the + inside alert, str is a string so it's not executed. For example if someone provides "document.cookie" in the form and hits submit, then the alert box is going to print "Error in document.cookie" (and not the actual cookie).
The only way this could be a potential threat is if you are including scripts that are not under your control from an untrustworthy source.
The malicious script could overwrite alert to be another function. For example, it could send the data passed to alert to its own servers.
The malicious script could overwrite the value of document.myform.field with an object containing a value property. The alert could be thus made to display a message that looked like a different error message, such as:
Error in authentication. Please go to www.phisherman.com and enter your user name and password.
If you are linking to scripts from untrustworthy sources, you have much greater security concerns than the above.
If you are linking to no such untrustworthy scripts, then no, this is not vulnerable to DOM-based XSS. form.field.value contains a string. It is not evaluated as script, escape characters have no effect, the string contained in the textbox will be displayed in the alert window. Nothing a user enters in that field could be used to harm your servers or corrupt your data based on the code you've posted.
I'd say that if your auditor is concerned with "DOM-based XSS" where-in a user might cause harm to your servers by manipulating the DOM, your auditor does not know much about DOM and browser-based JavaScript. A user can crack open a JavaScript console and execute all manner of scripts, including XMLHttpRequests to your server that can be made to look like they came from your own script. Precautions need to be made on the server for those types of attacks. Worrying about the security risks to the DOM or UI from user input in form fields is silly.
There is definitely no XSS problem with that.
What your "validate()" function does is:
Via the DOM API, copy a reference to a property of a DOM node (the "value" property of the <input> element) to a JavaScript variable.
Perform a JavaScript string concatenation operation. At that point, it absolutely does not matter what the string of characters is.
Pass the result string to the window.alert(). The "alert()" function always treats its argument strictly as a string. The only "special" character is newline, and all that does is cause text to wrap to a new line.
In particular, note that:
window.alert("<script>var u_r_so_hacked = true;</script>");
will show the "" tags just like that, angle brackets and all.
I currently have a simple <div contenteditable="true"> working, but, here's my problem.
Currently, the user can create a persistent XSS by inserting a <script> into the div, which I definitely do not want.
However, my current ideas to fix this are:
Allow only a and img tags
Use a textarea (not a good idea, because then have users copy and paste images)
What do you guys suggest?
You have to keep in mind that to prevent xss, you've GOT TO DO IT ON THE SERVER SIDE. If your rich text editor (ex YUI or tinyMCE) has some javascript to prevent a script tag from being inputted, that doesn't stop me from inspecting your http post requests, looking at the variable names you're using, and then using firefox poster to send whatever string I like to your server to bypass all client side validation. If you aren't validating user input SERVER SIDE then you're doing almost nothing productive to protect from XSS.
Any client side xss protection would have to do with how you render user input; not how you receive it. So, for example, if you encoded all input so it does not render as html. This goes away from what you want to accomplish though (just anchor and img tags). Just keep in mind the more you allow to be rendered the more possible vulnerabilities you expose.
That being said the bulk of your protection should come from the server side and there are a lot of XSS filters out there depending on what you're writing with (ex, asp.net or tomcat/derby/jboss) that you can look into.
I think you're on the right path by allowing ONLY a and img tags. The one thing you have to keep in mind is that you can put javascript commands into the src attributes of a tags, so take care to validate the href attributes. But the basic idea of "allow nothing and then change the filters to only allow certain things" (AKA whitelist filtering) is better than "allow everything and then filter out what I don't want" (AKA blacklist filtering).
In the comments below, Brian Nickel also said this which illustrates the point:
Everything but the elements and attributes you want to keep. I
know you mentioned it in your answer but that bears repeating since it
is so scary. <img onerror="stealMoney()">
The other thing you're going to want to do is define a XSSFilterRequest object (or something along those lines) and in a filter, override your requests so that any call to whatever your "getUrlParameter" and "getRequestParameter" objects run the request values through your xss filter. This provides a clean way to filter everything without rewriting existing code.
EDIT: A python example of xss filtering:
Python HTML sanitizer / scrubber / filter
Python library for XSS filtering?
What about using google caja (a source-to-source translator for securing Javascript-based web content)?
Unless you have xss validation on server side you could apply html_sanitize both to data sent from the user and data received from the server that is to be displayed. In worst case scenario you'll get XSSed content in database that will never be displayed to the user.
I'll be inserting content from remote sources into a web app. The sources should be limited/trusted, but there are still a couple of problems:
The remote sources could
1) be hacked and inject bad things
2) overwrite objects in my global names
space
3) I might eventually open it up for users to enter their own remote source. (It would be up to the user to not get in trouble, but I could still reduce the risk.)
So I want to neutralize any/all injected content just to be safe.
Here's my plan so far:
1) find and remove all inline event handlers
str.replace(/(<[^>]+\bon\w+\s*=\s*["']?)/gi,"$1return;"); // untested
Ex.
<a onclick="doSomethingBad()" ...
would become
<a onclick="return;doSomethingBad()" ...
2) remove all occurences of these tags:
script, embed, object, form, iframe, or applet
3) find all occurences of the word script within a tag
and replace the word script with html entities for it
str.replace(/(<[>+])(script)/gi,toHTMLEntitiesFunc);
would take care
<a href="javascript: ..."
4) lastly any src or href attribute that doesn't start with http, should have the domain name of the remote source prepended to it
My question: Am I missing anything else? Other things that I should definitely do or not do?
Edit: I have a feeling that responses are going to fall into a couple camps.
1) The "Don't do it!" response
Okay, if someone wants to be 100% safe, they need to disconnect the computer.
It's a balance between usability and safety.
There's nothing to stop a user from just going to a site directly and being exposed. If I open it up, it will be a user entering content at their own risk. They could just as easily enter a given URL into their address bar as in my form. So unless there's a particular risk to my server, I'm okay with those risks.
2) The "I'm aware of common exploits and you need to account for this ..." response ... or You can prevent another kind of attack by doing this ... or What about this attack ...?
I'm looking for the second type unless someone can provide specific reasons why my would be more dangerous than what the user can do on their own.
Instead of sanitizing (black listing). I'd suggest you setup a white list and ONLY allow those very specific things.
The reason for this is you will never, never, never catch all variations of malicious script. There's just too many of them.
don't forget to also include <frame> and <frameset> along with <iframe>
for the sanitization thing , are you looking for this?
if not, perhaps you could learn a few tips from this code snippet.
But, it must go without saying that prevention is better than cure. You had better allow only trusted sources, than allow all and then sanitize.
On a related note, you may want to take a look at this article, and its slashdot discussion.
It sounds like you want to do the following:
Insert snippets of static HTML into your web page
These snippets are requested via AJAX from a remote site.
You want to sanitise the HTML before injecting into the site, as this could lead to security problems like XSS.
If this is the case, then there are no easy ways to strip out 'bad' content in JavaScript. A whitelist solution is the best, but this can get very complex. I would suggest proxying requests for the remote content through your own server and sanitizing the HTML server side. There are various libraries that can do this. I would recommend either AntiSamy or HTMLPurifier.
For a completely browser-based way of doing this, you can use IE8's toStaticHTML method. However no other browser currently implements this.