Reputation: 586
I'd like to show a text with HTML execution (formated) in the browser so it will be easy to read BUT without any JavaScript execution. It's a large text and it's very hard to read between HTML tags. So, execute HTML but not JavaScript.
What I did: I loaded this text in an <iframe>
so I can have full control and I tried to show the text like this:
<script>
throw new Error('This is just to abort javascript');
</script>
<?php echo $text ?>
<script>
throw new Error('This is just to abort javascript');
</script>
The console does show an error but even so, if I have
$text = '<script>alert(1)</script>';
this script gets executed anyway.
Another XSS example that I'd like to avoid.
$text = '<a href="#" onmouseover="alert(1)">this is a fake url</a>';
Basically, abort any JavaScript execution from the page.
Thanks in advance!
Upvotes: 2
Views: 514
Reputation: 33588
You can specify a Content Security Policy to prevent any inline JavaScript from executing.
See here for browser compatibility.
It is also recommended to run any user input through an HTML sanitizer too, as this will help protect browsers without CSP support. Using BBcode or something like MarkDown is also recommended, rather than allowing users to enter raw HTML as this is much simpler (and complexity is the enemy of security).
Upvotes: 1
Reputation: 5942
Unfortunately this isn't really possible. The reason that that doesn't work is because the error stops that script from executing, but doesn't stop all scripts on the page from executing.
If you're trusting HTML input from the user, you're simply going to have XSS vulnerabilities, unless you try to parse their input and remove anything that could cause a javascript event to fire. Don't try this, you're in for a lot of heartache if you do.
Ultimately, this is why things like MarkDown and Textile exist.
I guess the answer to "what you should do" depends on what you're expecting the user to actually send you, but ultimately you should be running any user input through htmlentities and/or strip_tags
Upvotes: 3