Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSS - is it dangerous that innerText string can be HTML elements: script, div etc?

I'm working on the client side of a reviews web site.

the user can insert in the review description, any text including html element text (like : <script> console.log('hello') </script>), and style it with the basic text styles: italic, bold etc...

I wanted to test cross site scripting. so i played with it a little, and when using italic the elements get rendered as the innerText of the html element.

The innerText in the HTML looked like this:

html with script element and DOM js

I didn't saw the alert get executed, though.

can the user write text that will become valid HTML with it's events invoked ? if so, how ?

like image 865
Itay Tur Avatar asked Mar 21 '26 14:03

Itay Tur


1 Answers

What you're seeing in the elements/DOM tab is misleading you a bit. If you've used innerText (or more appropriately textContent, usually) to set the text of an element, it doesn't have tags in it. It has characters. Those characters can form tags from a display perspective, but they aren't tags and the browser doesn't treat them that way.

One way to see this is to see the HTML for them:

const target = document.getElementById("target");
target.textContent =
    `<script>alert("Hi!");<\/script>
    <div onclick='alert("Ho!");'>click me</div>
    <img onerror='alert("Hum!");' src=''>`;
console.log("textContent:", target.textContent);
console.log("innerHTML:", target.innerHTML);
<div id="target"></div>

Notice that the element doesn't contain a script tag, it contains the characters <, s, c, r, i, p, t, etc.


In contrast, using innerHTML leaves you wide open to XSS attacks:

const target = document.getElementById("target");
target.innerHTML =
    `<script>alert("Hi!");<\/script>
    <div onclick='alert("Ho!");'>click me</div>
    <img onerror='alert("Hum!");' src=''>`;
console.log("textContent:", target.textContent);
console.log("innerHTML:", target.innerHTML);
<div id="target"></div>

script tags inserted that way don't get run, but attribute-defined event handlers do, such as the error event on an img that has no src — and the code that that runs could add a script that would get executed:

const target = document.getElementById("target");
target.innerHTML =
    `<div onclick='alert("Ho!");'>click me</div>
    <img onerror='(function() {
        alert("Hi!");
        var s = document.createElement("script");
        s.textContent = &apos;alert("Hi from script");&apos;;
        document.body.appendChild(s);
    })()' src=''>`;
console.log("textContent:", target.textContent);
console.log("innerHTML:", target.innerHTML);
<div id="target"></div>
like image 93
T.J. Crowder Avatar answered Mar 23 '26 02:03

T.J. Crowder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!