1

For example, say there is a website where the user input is not properly sanitized, but these filters are still active. Anything typed is inserted into between two div tags.

If the input is "hello", it shows up in the source as "<div>hello</div>"

Tags also work. If the input is "<!--", then it would turn into "<div><!--</div>", turning much of the HTML on the page into a comment, breaking part of it.

However, script tags are filtered out. Inputting "<script>alert('xss')</script>" will return "<div>alert('xss')</div>", obviously not executing any javascript.

"javascript:" is filtered and turned into "nojavascript" if used as a source.

input:

<img src=javascript:alert('hi'); />

output:

<img src=nojavascript...alert('hi'); />

Another part of the filter protects it from "onload=" and other HTML event-based XSS attacks. If "onload=alert('xss')" is the input, it will not show up at all in the source.

So, my question is, would this website still be vulnerable to cross-site scripting, or is it safe due to the filter it uses?

  • do you tackle onerror onclick onhover and all too? – ndrix May 15 '17 at 22:32
  • Yep, those are also filtered out. If the input is "on...=", it is ignored. – Zachary Swanson May 15 '17 at 22:37
  • Do you filter by parsing the XML tree or regex-based? – Arminius May 16 '17 at 0:07
9

So, my question is, would this website still be vulnerable to cross-site scripting, or is it safe due to the filter it uses?

It's not safe. You didn't fully describe your filtering mechanism, but a blacklist-based XSS filter is guaranteed to leave some loopholes.

Examples

Do you consider the href attribute of link tags? A click on this link would trigger:

<a href="javascript:alert(1)">Click me<a>

If you filter out javascript:, are your checks case-insensitive?

<a href="JaVaScRiPt:alert(1)">Click me<a>

And do you consider different ways of encoding? E.g.:

<a href="javascript&#x3a;alert(1)">Click me</a>

Do you consider frames? It's certainly not enough to filter out javascript: since an attacker could also use other schemes, e.g.:

<iframe src="data:text/html,<script>alert(1)</script>">

If you're thinking that the <script> tag inside the frame src would be detected by your filter - it can of course be encoded, e.g.:

<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">

Also, do you consider that <iframe> has a srcdoc attribute?

<iframe srcdoc="<script>alert(1)</script>">

Again, there are many ways to encode this, e.g.:

<iframe srcdoc="&#x3C;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3E;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;&#x3C;&#x2F;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3E;">

The list goes on. (What about SVGs, forms, meta tags, obscure vendor-specific protocols, embedded flash applets, CSS, ... ?)

The correct approach is to use a whitelist of allowed tags and attributes, and parsing the resulting DOM tree instead of regex-based string replacements.

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.