innerHTML
property JS-S1012The innerHTML
property is capable of directly changing the DOM structure, thereby opening up possibilities for XSS attacks.
If you only want to change the text inside an HTML element, consider using the innerText or textContent property instead.
Avoid assigning values that are fetched from 3rd party sources to HTMLElement#innerHTML
without proper sanitization.
If you must do so, validate and sanitize the data before assignment.
NOTE: If this issue was raised on a code snippet that you're sure was sanitized, consider adding a skipcq comment explaining the reason for the snippet's safety. Alternatively, you could disable this issue for your project in settings.
Assigning values to innerHTML
without proper sanitization can open us up to XSS attacks.
For example, consider this snippet:
const res = await axios.get("www.website.com/api/resource/id")
const myDiv = document.getElementById("#my-div")
myDiv.innerHTML = "<p>" + res.data + "</p>"
This snippet is harmless so long as website
's API is not malicious, or compromised.
However, an attacker may change the response to that endpoint to '<a href="www.other-website.com">Click me!</a>'
.
This would alter the DOM structure to contain a link that might lead to the attacker's website.
This can be avoided with proper sanitization prior to the assignment to the innerHTML
property.
// Scenario 1:
fetch("www.website.com").then((res) => {
const myDiv = document.querySelector("#foo")
myDiv.innerHTML = res.data.html
})
// Scenario 2:
const res = await axios.get("fubar.com")
const json = await res.json()
document.getElementById("my-div").innerHTML = `<span class="important"> ${json.data.markup} </span>`
fetch("www.website.com").then((res) => {
const myDiv = document.querySelector("#foo")
myDiv.innerText = res.data.html
})
const res = await axios.get("fubar.com")
const json = await res.json()
// Use a sanitizer function to ensure there are no anomalies in received data
const secureMarkup = sanitize(json.data.markup)
document.getElementById("my-div").innerHTML = `<span class="important"> ${secureMarkup} </span>`