How to resolve XSS vulnerabilities while using innerHTML - javascript

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.

Related

How to protect against Encoded URL XSS Attack

I got following 2 questions as:
1) How to protect from this kind of XSS Attacks?
https://www.example.com/index.php?&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041
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="&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041">
//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.

Failed DOM-based XSS. Inserting script throght innerHTML

I wanted to show my students example of DOM-base XSS attack. I thought that inserting malicious script by innerHTML will by enough. But to my surprise when I insert script it seems to be not invoked.
Example is here https://jsfiddle.net/vo9baffu/6/ example
My question: is it possible to do DOM-based XSS attack in a way presented in my example. If not then way and what should I change?
BTW.
If you know some good examples of DOM-based XSS please post in comment.
Use the good ol' image:
<img src="/bad.png" onerror="alert(-2)" />
Full code:
function showName() {
tt = "script";
badCode = "John<img onerror='alert(-2)' src='/bad.png'>";
console.log(badCode);
document.getElementById("name").innerHTML = badCode;
}
Where /bad.png should trigger onerror.
And your JSFiddle
Briefly: You can't make a DOM-based XSS attack in the way presented in your example.
You have to include jQuery in your HTML and use the html() method instead. This will will accomplish exactly what you ask for, because the html() method will evaluate the code embedded in the script tag.
With pure JavaScript, you can't make an XSS attack, because the script you insert will not execute in most cases. That happens, because the inline script only executes when the original page is parsed.
You can show your students an XSS attack by using an img tag and an error event as shown below:
<img src="whatever.png" onerror="alert('XSS')" />
as shown in this fiddle .

What HTML tags would be considered dangerous if stored in SQL Server?

Considering issues like CSRF, XSS, SQL Injection...
Site: ASP.net, SQL Server 2012
I'm reading a somewhat old page from MS: https://msdn.microsoft.com/en-us/library/ff649310.aspx#paght000004_step4
If I have a parametrized query, and one of my fields is for holding HTML, would a simple replace on certain tags do the trick?
For example, a user can type into a WYSIWYG textarea, make certain things bold, or create bullets, etc.
I want to be able to display the results from a SELECT query, so even if I HTMLEncoded it, it'll have to be HTMLDecoded.
What about a UDF that cycles through a list of scenarios? I'm curious as to the best way to deal with the seemingly sneaky ones mentioned on that page:
Quote:
An attacker can use HTML attributes such as src, lowsrc, style, and href in conjunction with the preceding tags to inject cross-site scripting. For example, the src attribute of the tag can be a source of injection, as shown in the following examples.
<img src="javascript:alert('hello');">
<img src="java
script:alert('hello');">
<img src="java
script:alert('hello');">
An attacker can also use the <style> tag to inject a script by changing the MIME type as shown in the following.
<style TYPE="text/javascript">
alert('hello');
</style>
So ultimately two questions:
Best way to deal with this from within the INSERT statement itself.
Best way to deal with this from code-behind.
Best way to deal with this from within the INSERT statement itself.
None. That's not where you should do it.
Best way to deal with this from code-behind.
Use a white-list, not a black-list. HTML encode everything, then decode specific tags that are allowed.
It's reasonable to be able to specify some tags that can be used safely, but it's not reasonable to be able to catch every possible exploit.
What HTML tags would be considered dangerous if stored in SQL Server?
None. SQL Server does not understand, nor try to interpret HTML tags. A HTML tag is just text.
However, HTML tags can be dangerous if output to a HTML page, because they can contain script.
If you want a user to be able to enter rich text, the following approaches should be considered:
Allow users (or the editor they are using) to generate BBCode, not HTML directly. When you output their BBCode markup, you convert any recognised tags to HTML without attributes that contain script, and any HTML to entities (& to &, etc).
Use a tried and tested HTML sanitizer to remove "unsafe" markup from your stored input in combination with a Content Security Policy. You must do both otherwise any gaps (and there will be gaps) in the sanitizer could allow an attack, and not all browsers full support CSP yet (IE).
Note that these should be both be done on point of output. Store the text "as is" in your database, simply encode and process for the correct format when output to the page.
Sanitize html both on the client and on the server before you stuff any strings into SQL.
Client side:
TinyMCE - does this automatically
CKEditor - does this automatically
Server side:
Pretty easy to do this with Node, or the language/platform of your choice.
https://www.realwebsite.com
the link above shows www.realwebsite.com while it actually takes you to www.dangerouswebsite.com...
<a '
href="https://www.dangerouswebsite.com">
https://www.realwebsite.com
<'/a>
do not include the random ' in the code I put it there to bypass activating the code so you can see the code instead of just the link. (btw most websites block this or anything if you add stuff like onload="alert('TEXT')" but it can still be used to trick people into going to dangerous websites... (although its real website pops up on the bottom of your browser, some people don't check it or don't understand what it means.))

Secure database entry against XSS

I'm creating an app that retrieves the text within a tweet, store it in the database and then display it on the browser.
The problem is that I'm thinking if the text has PHP tags or HTML tags it might be a security breach there.
I looked into strip_tags() but saw some bad reviews. I also saw suggestions to HTML Purifier but it was last updated years ago.
So my question is how can I be 100% secure that if the tweet text is "<script> something_bad() </script>" it won't matter?
To state the obvious the tweets are sent to the database from users so I don't want to check all individually before displaying them.
You are NEVER 100% secure, however you should take a look at this. If you use ENT_QUOTES parameter too, currently there are no ways to inject ANY XSS on your website if you're using valid charset (and your users don't use outdated browsers). However, if you want to allow people to only post SOME html tags into their "Tweet" (for example <b> for bold text), you will need to take a deep look at EACH whitelisted tag.
You've passed the first stage which is to recognise that there is a potential issue and skipped straight to trying to find a solution, without stopping to think about how you want to deal the scenario of the content. This is a critical pre-cusrsor to solving the problem.
The general rule is that you validate input and escape output
validate input
- decide whether to accept or reject it it in its entirety)
if (htmlentities($input) != $input) {
die "yuck! that tastes bad";
}
escape output
- transform the data appropriately according to where its going.
If you simply....
print "<script> something_bad() </script>";
That would be bad, but....
print JSONencode(htmlentities("<script> something_bad() </script>"));
...then you'd would have done something very strange at the front end to make the client susceptivble to a stored XSS attack.
If you're outputting to HTML (and I recommend you always do), simply HTML encode on output to the page.
As client script code is only dangerous when interpreted by the browser, it only needs to be encoded on output. After all, to the database <script> is just text. To the browser <script> tells the browser to interpret the following text as executable code, which is why you should encode it to <script>.
The OWASP XSS Prevention Cheat Sheet shows how you should do this properly depending on output context. Things get complicated when outputting to JavaScript (you may need to hex encode and HTML encode in the right order), so it is often much easier to always output to a HTML tag and then read that tag using JavaScript in the DOM rather than inserting dynamic data in scripts directly.
At the very minimum you should be encoding the < & characters and specifying the charset in metatag/HTTP header to avoid UTF7 XSS.
You need to convert the HTML characters <, > (mainly) into their HTML equivalents <, >.
This will make a < and > be displayed in the browser, but not executed - ie: if you look at the source an example may be <script>alert('xss')</script>.
Before you input your data into your database - or on output - use htmlentities().
Further reading: https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet

jQuery Prepend Security

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

Categories