Alternative to define in-line javascript expressions - javascript

I have been learning web application security penetration testing . The scenario is, there is a cross site scripting vulnerability in a test environment demo web application which is developed for practicing. I have a xss payload which is javascript expressions based :
<div style="width: expression(alert(/XSS/))"></div>
I know the expressions are deprecated since IE 8 .It works fine in IE7. So , when i input above payload , Web app returns with
<div></div>
It rips off all other attributes and values. But when i alter the payload like
<div style="width: expression'(alert(/XSS/))'">
Its not a valid payload means it won't execute. So, i am trying to figure out if there is any alternative to define expression in in-line style attribute like if we can place something else other than single_quote which won't break the code . Or if there is any other way to execute javascript via style attribute.

expression() is the only way to dynamically specify html node attributes. It takes any valid JScript expression as an argument. So technically there is no way to execute javascript via style attribute on an html node (JScript !== javascript).
The reason this functionality doesn't exist, (or has been deprecated) is because it creates a pretty big security vulnerability. If you want to have dynamic html elements, you'd tackle that with css, specifically through media queries. But if you want to go down this path, try checking out the expression() documentation.
In javascript (JScript as well), () invoke a function. So throwing ' or " after an expression name, before invoking it, is invalid syntax. There's probably something else you can place besides "single_quote" which won't break the code, but you wouldn't place it before the (). Try looking up JScript syntax. Here's one last resource that may help.

Related

Selector interpreted as HTML on my website. Can an attacker easily exploit this?

I have a website that is only accessible via https.
It does not load any content from other sources. So all content is on the local webserver.
Using the Retire.js Chrome plugin I get a warning that the jquery 1.8.3 I included is vulnerable to 'Selector interpreted as HTML'
(jQuery bug 11290)
I am trying to motivate for a quick upgrade, but I need something more concrete information to motivate the upgrade to the powers that be.
My question are :
Given the above, should I be worried ?
Can this result in a XSS type attack ?
What the bug is telling you is that jQuery may mis-identify a selector containing a < as being an HTML fragment instead, and try to parse and create the relevant elements.
So the vulnerability, such as it is, is that a cleverly-crafted selector, if then passed into jQuery, could define a script tag that then executes arbitrary script code in the context of the page, potentially taking private information from the page and sending it to someone with malicious (or merely prurient) intent.
This is largely only useful if User A can write a selector that will later be given to jQuery in User B's session, letting User A steal information from User B's page. (It really doesn't matter if a user can "tricky" jQuery this way on their own page; they can do far worse things from the console, or with "save as".)
So: If nothing in your code lets users provide selectors that will be saved and then retrieved by other users and passed to jQuery, I wouldn't be all that worried. If it does (with or without the fix to the bug), I'd examine those selector strings really carefully. I say "with or without the bug" because if you didn't filter what the users typed at all, they could still just provide an HTML fragment where the first non-whitespace character is <, which would still cause jQuery to parse it as an HTML fragment.
As the author of Retire.js let me shed some light on this. There are two weaknesses in older versions of jQuery, but those are not vulnerabilities by themselves. It depends on how jQuery is used. Two examples abusing the bugs are shown here: research.insecurelabs.org/jquery/test/
The two examples are:
$("#<img src=x onerror=...>")
and
$("element[attribute='<img src=x onerror=...>'")
Typically this becomes a problem if you do something like:
$(location.hash)
This was a fairly common pattern for many web sites, when single page web sites started to occur.
So this becomes a problem if and only if you put untrusted user data inside the jQuery selector function.
And yes the end result is XSS, if the site is in fact vulnerable. https will not protect you against these kinds of flaws.

Security of Angular expressions

I am going through the PhoneCat tutorial for AngularJS. Everything is explained really well, so i was following along until i hit step 6 in which links are generated dynamically from angular expressions:
http://localhost:8000/app/{{phone.imageUrl}}
While the tutorial states that ngSrc is preventing the browser from making http requests to invalid locations (edit: apparently the tutorial means the browser will only call the link after the expression got evaluated. See the "Experiments" section in the provided link.), i am now wondering of how secure angular-expressions are in general. Since the phone.imageUrl is loaded externally, it theoretically could contain malicious content and i would like to understand why this would not matter to my webapp.
Obviously the content of expressions gets escaped in some way, so including the following in your code will just print out some text:
<img ng-src="{{""><script>alert('UNSAFE!')</script>"}}">
but i would like to know if there are some "rules" that you need to be aware of to keep your webapp secure. Would for instance compiling the above code via
var template = "<img ng-src="{{""><script>alert('UNSAFE!')</script>"}}">";
var something = $compile(template);
result in executing the script when the DOM is loaded? Are there "things" that you should not do in your webapp when you can't ensure that the angular expressions contain the expected content?
As far as I know angular always escapes any data bound to elements unless you tell it not to do so.
Your example on the other hand works differently – maybe you're a little unsure how angular works:
var template = "<img ng-src="{{userInput}}">";
var something = $compile(template)({userInput: "\"><script>alert('UNSAFE!')</script>\""});
So the template, which you have full control of, get's first compiled and then the expression is bound to it completely escaped (no html allowed).
I'd probably not compile external code ($compile(userinput)) without sanitizing it first – but that would mean you may be doing something wrong. If you code the right way, you will use $compile only in some edge cases. Otherwise you may stay calm since angular will take care of unsafe input.
If you need to bind html to template, then you can include ngSanitize. Otherwise angular won't let you bind unsafe html, unless you tell the $sce service to trust it.
In conclusion, I would not worry about binding data from untrusted sources to my template.

Will non-IE browsers use script inside a tag with type="text/jscript"?

I inherited an ancient codebase that includes pages with <script type="text/jscript"> -- yes, my life really does suck that much. The script appears to do nothing in modern, decent browsers (FF and Chrome, for a start) and I'm wondering if the stated script type is causing it to be ignored. I spent some time trying to figure out what's going on, and I see things like
As explained by JavaScript guru Douglas Crockford in his talk entitled The JavaScript Programming Language on YUI Theater, "[Microsoft] did not want to deal with Sun about the trademark issue, and so they called their implementation JScript. A lot of people think that JScript and JavaScript are different but similar languages. That's not the case. They are just different names for the same language, and the reason the names are different was to get around trademark issues."
on Wikipedia. So Javascript == JScript? But then, I see conflicting information, like this answer which seems to suggest that script that's declared as JScript will only run in IE.
So: can I just change the type tag and everything will work fine? Is there a simple process for conversion? If not, I may just scrap the whole thing and start over.
From HTML 5 chapter 4.3
7) If the user agent does not support the scripting language given by the script block's type for this script element, then the user agent must abort these steps at this point. The script is not executed.
That same chapter also says
If either:
the script element has a type attribute and its value is the empty string, or
the script element has no type attribute but it has a language attribute and that attribute's value is the empty string, or
the script element has neither a type attribute nor a language attribute, then
...let the script block's type for this script element be "text/javascript".
so I would just remove type="text/jscript" save a bit on bandwidth and live happily ever after.
So Javascript == JScript?
JScript is what Microsoft calls JavaScript
But then, I see conflicting information, like this answer which seems to suggest that script that's declared as JScript will only run in IE.
That doesn't conflict. It just means that other browsers don't recognise the mime type.
Browsers will ignore script elements with a type they do not recognise. text/jscript is non-standard and most browsers don't recognise it (Internet Explorer considers it an alias for text/javascript).
can I just change the type tag and everything will work fine?
Probably. The script might depend on other proprietary Microsoft—isms (such as document.all) or other non-standard behaviour (automatic id attribute to JS global conversion or treating CSS lengths that are missing a unit as pixels) though.
The other answer you linked to is completely incorrect. There are no differences between JScript and JavaScript. Changing the script type to "text/javascript" should work (unless the intent of the author was to force it so that only IE ran the script)
the type= requirements have been taken out of html5. I believe the proper xhtml code would be ...
<script type="text/javascript">
<![CDATA[
// content of your Javascript goes here
]]>
</script>
... but browsers did not follow the requirements of xhtml of forcing an error. Most web hosts keep the delivery of xhtml and html docs as MIME-type "text/html", not the "application/xhtml+xml" which should force an error if the xhtml does not validate.
HTML4 uses are variety of types ... http://www.w3.org/TR/html4/interact/scripts.html ... but browsers do not force html4 validation.
vscript, tcl don't have common support - we are talking about Javascript or any of the other names it gets as in becomes a more powerful language.
A bogus "type" attribute will definitely make scripts not work. The browser thinks you don't want it to run the script, basically.
Really, the "type" attribute is not necessary unless you definitely don't want the browser to run a script (which people do when their "scripts" are actually template bodies, or other data like that). You could either change all yours to "text/javascript" or just get rid of the attribute entirely.

How to prevent JavaScript injection (XSS) when JSTL escapeXml is false

I have a form that people can add their stuff. However, in that form, if they enter JavaScript instead of only text, they can easily inject whatever they want to do. In order to prevent it, I can set escapeXml to true, but then normal HTML would be escaped as well.
<td><c:out value="${item.textValue}" escapeXml="true" /></td>
Is there any other way to prevent JavaScript injection rather than setting this to true?
I'd recommend using Jsoup for this. Here's an extract of relevance from its site.
Sanitize untrusted HTML
Problem
You want to allow untrusted users to supply HTML for output on your website (e.g. as comment submission). You need to clean this HTML to avoid cross-site scripting (XSS) attacks.
Solution
Use the jsoup HTML Cleaner with a configuration specified by a Whitelist.
String unsafe =
"<p><a href='http://example.com/' onclick='stealCookies()'>Link</a></p>";
String safe = Jsoup.clean(unsafe, Whitelist.basic());
// now: <p>Link</p>
So, all you basically need to do is the the following during processing the submitted text:
String text = request.getParameter("text");
String safe = Jsoup.clean(text, Whitelist.basic());
// Persist 'safe' in DB instead.
Jsoup offers more advantages than that as well. See also Pros and Cons of HTML parsers in Java.
You need to parse the HTML text on the server as XML, then throw out any tags and attributes that aren't in a strict whitelist.
(And check the URLs in href and src attributes)
This is exactly the intent of the OWASP AntiSamy project.
The OWASP AntiSamy project is a few things. Technically, it is an API for ensuring user-supplied HTML/CSS is in compliance within an application's rules. Another way of saying that could be: It's an API that helps you make sure that clients don't supply malicious cargo code in the HTML they supply for their profile, comments, etc., that get persisted on the server. The term "malicious code" in regards to web applications usually mean "JavaScript." Cascading Stylesheets are only considered malicious when they invoke the JavaScript engine. However, there are many situations where "normal" HTML and CSS can be used in a malicious manner. So we take care of that too.
Another alternative is the OWASP HTMLSanitizer project. It is faster, has less dependencies and actively supported by the project lead as of now. I don’t think it has gone through any GA/Stable release yet so you should consider that when evaluating this library.

JavaScript-friendly alternative to the f(x) = y JScript idiom that's used when setting CDO.Message options

I have an ASP page written in JScript that sends e-mails using CDO.Message. For specifying an SMTP server (and other options) I'm doing something like this:
mail.Configuration.Fields.Item(
"http://schemas.microsoft.com/cdo/configuration/smtpserver") =
"smtp.example.com";
Now, here comes the catch. I have this code in a stand-alone include file that I include in an HTML page as JavaScript so that I can run unit tests against it in a browser (using JsUnit etc.). I have JavaScript mock objects (Server, Request, etc.) that create a mock ASP environment for the included JScript code. The only problem I have left is with the CDO.Message option setting. Since the f(x) = y syntax that's used in the above code excerpt is not valid JavaScript (invalid left-hand operand), I can't run this piece of code (as it is) within a browser. I'm currently simply bypassing it in my unit test with a conditional that detects whether the environment is truly ASP.
I don't think that there's a JavaScript workaround to this. I'm looking for an alternative syntax (that may use the ActiveX interfaces differently) to setting CDO.Message options that would also be syntactically valid JavaScript.
I figured out the answer when looking at the C++ code example at http://msdn.microsoft.com/en-us/library/ms526318(EXCHG.10).aspx.
The solution is to make the assignment explicitly to the Value property:
mail.Configuration.Fields.Item(
"http://schemas.microsoft.com/cdo/configuration/smtpserver").Value =
"smtp.example.com";
This way, the code above is valid JavaScript than can be tested with a mock Configuration object.
I've been having the same problem when writing server-side Javascript for IIS, That f(x) = y syntax was failing in my IDE's syntax checker. The solution I found helpful was JScript conditional comments like so:
f(x)/*#cc_on#if(0)*/[0]/*#end#*/ = y;
It puts the subscript index [0] on the end except when running in Microsoft's JScript engine. But, admittedly my solution is a bit hacky. I think in most cases yours is cleaner, so thanks for sharing it.
-Simon

Categories

Resources