InnerHTML loopholes
Early front-end developers often used the element.innerhtml () method when writing code, but this method has a lot of bugs. Here’s an example:
var element = document.getElementById("root");
element.innerHTML = '';
Copy the code
This looks like a simple XSS attack. Execute and find that nothing happened . In fact, the built-in security mechanism already parses and executes the incoming DOM. Here I looked up the document, and it said:
HTML 5 specifies that the
var element = document.getElementById("root");
element.innerHTML = "<img src=x onerror=\"alert('XSS Attack')\">";
Copy the code
At this point, our injected script is still executed.
Security plan
- use
textContent
element.textContent = "<img src=x onerror=\"alert('XSS Attack')\">";
Copy the code
At this point, we will access as a string, thus avoiding script execution.
- Purify the content passed into the DOM
TextContent can solve some of the problems, but it doesn’t solve all of them, and when we need to add additional tags, we still need to use innerHTML. Such as:
element.innerHTML = "<h1>" + yourString + "</h1>";
Copy the code
At this point, we have no choice but to cleanse yourString:
var sanitizeHTML = function(str) {
var temp = document.createElement("div");
temp.textContent = str;
return temp.innerHTML;
};
Copy the code
Translate special characters by creating a temporary DIV and storing the content in textContent, and then returning the translated content with innerHTML, because innerHTML prevents the translated character from being converted back to its untranslated state.
var div = document.getElementById("root");
div.innerHTML =
"<h1>" +
sanitizeHTML("<img src=x onerror=\"alert('XSS Attack')\">") +
"</h1>";
Copy the code
This is a more general approach.
reference
Preventing cross-site scripting attacks when using innerHTML in vanilla JavaScript