The Property Rule prevents unsafe assignment to DOM properties like innerHTML and outerHTML that can lead to XSS vulnerabilities. It validates assignment expressions and ensures only safe values are assigned to dangerous properties.
Creates an ESLint rule that validates AssignmentExpression nodes for unsafe property assignments.
/**
* Creates the property rule for ESLint
* @param context - ESLint rule context with options and reporting capabilities
* @returns ESLint rule visitor object with AssignmentExpression handler
*/
const PropertyRule = {
meta: {
type: "problem",
docs: {
description: "ESLint rule to disallow unsanitized property assignment",
category: "possible-errors",
url: "https://github.com/mozilla/eslint-plugin-no-unsanitized/tree/master/docs/rules/property.md"
},
schema: [PropertyRuleOptions, object]
},
create(context: ESLintRuleContext): PropertyRuleVisitor
};
interface PropertyRuleVisitor {
AssignmentExpression(node: AssignmentExpressionNode): void;
}
interface AssignmentExpressionNode {
left: {
property: {
name: string;
};
};
right: any;
operator: string;
}Configure which escape functions are allowed and enable variable tracing.
interface PropertyRuleOptions {
/** Configuration for allowed escape functions */
escape?: {
/** Array of allowed tagged template function names */
taggedTemplates?: string[];
/** Array of allowed escaping method names */
methods?: string[];
};
/** Enable variable tracing to validate identifiers */
variableTracing?: boolean;
}The rule checks these properties by default:
const defaultRuleChecks = {
/** Check unsafe assignment to innerHTML */
innerHTML: {},
/** Check unsafe assignment to outerHTML */
outerHTML: {}
};The rule validates specific assignment operators and ignores safe ones:
// Operators that are considered safe and not checked
const PERMITTED_OPERATORS = [
"-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
"|=", "^=", "&=", "**="
];
// Operators that require safety validation
const CHECK_REQUIRED_OPERATORS = ["=", "+=", "||=", "&&=", "??="];Usage Examples:
// These assignments will trigger the rule
element.innerHTML = userInput; // Unsafe: direct assignment
element.innerHTML += "<span>" + data + "</span>"; // Unsafe: concatenation
// These assignments are allowed
element.innerHTML = "<p>Static content</p>"; // Safe: literal
element.innerHTML = escapeHTML`<p>${data}</p>`; // Safe: tagged template
element.innerHTML = Sanitizer.escapeHTML("<p>" + data + "</p>"); // Safe: escape method
element.innerHTML *= 2; // Safe: permitted operator
// Variable tracing (when enabled)
const safeContent = escapeHTML`<div>${userInput}</div>`;
element.innerHTML = safeContent; // Safe: traced variableThe rule reports unsafe assignments with descriptive messages:
// Basic unsafe assignment
"Unsafe assignment to innerHTML"
// With variable tracing details
"Unsafe assignment to innerHTML (Variable 'content' initialized with unsafe value at 15:8)"