Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

Why does this vector :

<svg><script>alert&#40/1/.source&#41</script>

works in http://jsfiddle.net/ZgPY4/2/ and this one

<script>alert&#40/1/.source&#41</script>

doesn't. How is <svg> making it work?

share|improve this question
    
When <svg> used ASCII encoding is possible otherwise not, anyway here is xss js append payload when following characters are NOT allowed ? = ( ) ; : ----------- might someone find it usefull ;) http://jsfiddle.net/sh00pac/GrnqV/ –  sh00pac Jun 1 '13 at 15:37

2 Answers 2

up vote 14 down vote accepted

HTML <script> has special powers other elements don't: it is a "CDATA element". That means that any < or & characters up to the end of the element are taken as literally meaning those characters. So what is passed to the JS interpreter is:

alert&#40/1/.source&#41

which is obviously not valid JS syntax.

The concept of a "CDATA element" comes from the SGML world from which HTML developed. But SVG comes from the XML world where things are simplified and there are no CDATA elements. Consequently the SVG <script> element has no special powers: inside an SVG script, < introduces a tag and & introduces an entity or character reference.

Consequently the &#40 gets parsed to ( and the resulting string passed to the JS interpreter is:

alert(/1/.source)

In XML terms the <script> element is in the HTML namespace and the <svg><script> element is in the SVG namespace, so they are different elements. HTML5 makes this all less clear by hiding the namespace prefixes and applying a non-XML parser to the SVG (which is why &#40 works despite it being non-well-formed; should be &#40;).

share|improve this answer
    
Brilliant explanation! +1. May I, then, ask what the equivalent way of getting this script to work without the SVG tag would be? –  Lex May 31 '13 at 10:31
4  
You'd just go with the unescaped version, <script>alert(/1/.source)</script>. You would only need to consider the SVG workaround if you were dealing with an input filter that blocked use of ( and ) characters. There are many funny little workarounds for particular filters that arbitrarily block certain characters. –  bobince May 31 '13 at 13:10
    
Much appreciated. –  Lex May 31 '13 at 13:24
1  
FWIW, we did this, because the SVG WG wanted the XML serialization of SVG to be copyable and pasteable into the HTML serialization in a text editor. –  hsivonen Jun 7 '13 at 13:32
2  
Moral of the story: Always sanitize user-provided markup by parsing with a real HTML parser, applying a whitelist-based sanitizer to the parser output and re-serializing the sanitizer output. –  hsivonen Jun 7 '13 at 13:34

The # (hash,sharp,pound) breaks your Javascript. Inside of an <svg> tag pair (your closing tag is not provided) the entity number is being translated to it's proper character reference as it's rendered as html, then the engine executes the ECMA script (which it is allowed to do for drawing).

OWASP.org documents this as hex encoding without semicolons.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.