3

I found a reflected XSS vulnerability that parses HTML code, but if you put a closing bracket the filter deletes it.

Is there any code for a proof of concept that I can run without any closing brackets (>)?

Thanks

  • Does it accept things like <!-- to comment out the rest of the page? Even if it doesn't allow script execution, it'll probably break the page enough for the owners to see the problem when you report it! – Matthew Jan 17 '17 at 13:53
  • I once bypassed such a filter by using the unicode equivalent of a closing bracket (but it depends on the server side of course if it will decode it): \u003e – stanko Jan 17 '17 at 14:05
  • @pineappleman thanks for the suggestion, though I tried unicode and it doesn't parse – Jack Jan 17 '17 at 14:26
  • 3
    Did you try omitting the closing bracket? If you put something like: <img src=n onerror="alert(document.cookie)" test= and other html tags follow later on the page, the tag might still get parsed. – Denis Jan 17 '17 at 15:18
1

Is there any code for a proof of concept that I can run without any closing brackets (>)?

No, regular tags don't work without a closing bracket. However, you can use comments.

If your browser's tokenizer adheres to the W3C HTML syntax specification (which modern browsers should do), it won't emit a tag token unless you supply a closing bracket (>). You can confirm this by looking up the state transitions in the tokenizer.

Say, you inject <script which means now you are in the Tag name state. Here are your options:

8.2.4.10 Tag name state

Consume the next input character:

"tab" (U+0009)
"LF" (U+000A)
"FF" (U+000C)
U+0020 SPACE
    Switch to the before attribute name state.
"/" (U+002F)
    Switch to the self-closing start tag state.
">" (U+003E)
    Switch to the data state. Emit the current tag token.
Uppercase ASCII letter
    Append the lowercase version of the current input character (add 0x0020 to the character's code point) to the current tag token's tag name.
U+0000 NULL
    Parse error. Append a U+FFFD REPLACEMENT CHARACTER character to the current tag token's tag name.
EOF
    Parse error. Switch to the data state. Reconsume the EOF character.
Anything else
    Append the current input character to the current tag token's tag name. 

Only > emits the tag token, but you're not allowed to use it. If the document ends right there (EOF), you are producing a parse error and not emitting the token. An exception to that behavior are comments and DOCTYPE declarations.

Now let's say you get into the Comment state via <!--. Then these are the options:

8.2.4.48 Comment state

Consume the next input character:

"-" (U+002D)
    Switch to the comment end dash state
U+0000 NULL
    Parse error. Append a U+FFFD REPLACEMENT CHARACTER character to the comment token's data.
EOF
    Parse error. Switch to the data state. Emit the comment token. Reconsume the EOF character.
Anything else
    Append the current input character to the comment token's data. 

As you can see, an end-of-file still emits the comment token. So even if you can't close a tag, you could inject a comment that comments out following text. Also, DOCTYPE tokens (<!DOCTYPE) and basically anything starting with <! will be emitted.


Obviously, if your injection point is surrounded by any HTML tags, you don't have to close the tag yourself as any subsequent > will be applied and do that for you. @tim has given an example for that in his answer.

1

That depends on the rest of the page. If it contains a closing bracket, you can likely use that to close whatever tag you have opened.

An example would be:

<img src=no onerror=alert(1) foo=       // the input
<div>example</div>                      // the rest of the page

Which would be executed by at least Chrome and Firefox.

1

The following XSS injections will execute without any accompanying closing tag.

<body/onload=alert(1) <svg/onload=alert(1) <iframe/onload=alert(1)

As for why this happens, I am not sure. Someone else might be able to answer that, but it works.

Fiddle example: https://jsfiddle.net/vh9xw9cw/1/

  • Which browser? I found a similar claim here, but couldn't reproduce it. Are you sure it isn't just jsfiddle that makes it work? – tim Dec 18 '17 at 10:49
  • It will work in any browser. Try creating a simple html file and opening it. <html><body><svg/onload=alert(123)</body></html> This works for me in Chrome, Firefox, and Brave. Most likely, the reason that you are having trouble reproducing is that your payload is getting blocked by your browser's XSS filter. If that's the case, I would suggest trying Firefox, as it doesn't have an XSS filter. – Brian Williams Dec 30 '17 at 18:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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