@microsoft/eslint-plugin-sdl
Version:
ESLint plugin focused on common security issues and misconfigurations discoverable during static testing as part of Microsoft Security Development Lifecycle (SDL)
83 lines (74 loc) • 2.71 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* @fileoverview Rule to disallow assignment to innerHTML or outerHTML properties
* @author Antonios Katopodis
*/
;
const astUtils = require("../ast-utils");
module.exports = {
meta: {
type: "suggestion",
fixable: "code",
schema: [],
docs: {
description:
"Assignments to [innerHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML)/[outerHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML) properties or calls to [insertAdjacentHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML) method manipulate DOM directly without any sanitization and should be avoided. Use document.createElement() or similar methods instead.",
url: "https://github.com/microsoft/eslint-plugin-sdl/blob/master/docs/rules/no-inner-html.md"
},
messages: {
noInnerHtml: "Do not write to DOM directly using innerHTML/outerHTML property",
noInsertAdjacentHTML: "Do not write to DOM using insertAdjacentHTML method"
}
},
create: function (context) {
const fullTypeChecker = astUtils.getFullTypeChecker(context);
function mightBeHTMLElement(node) {
const type = astUtils.getNodeTypeAsString(fullTypeChecker, node, context);
return type.match(/HTML.*Element/) || type === "any";
}
return {
"CallExpression[arguments.length=2] > MemberExpression.callee[property.name='insertAdjacentHTML']"(
node
) {
// Ignore known false positives
if (
node.parent != undefined &&
node.parent.arguments != undefined &&
node.parent.arguments.length >= 1 &&
node.parent.arguments[1] != undefined &&
// element.insertAdjacentHTML('')
node.parent.arguments[1].type === "Literal" &&
node.parent.arguments[1].value === ""
) {
return;
}
if (mightBeHTMLElement(node.object)) {
context.report({
node: node,
messageId: "noInsertAdjacentHTML"
});
}
},
"AssignmentExpression[left.type='MemberExpression'][left.property.name=/innerHTML|outerHTML/]"(
node
) {
// Ignore known false positives
if (
node.right != undefined &&
// element.innerHTML = ''
node.right.type === "Literal" &&
node.right.value === ""
) {
return;
}
if (mightBeHTMLElement(node.left.object)) {
context.report({
node: node,
messageId: "noInnerHtml"
});
}
}
};
}
};