or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdmethod-rule.mdplugin-configuration.mdproperty-rule.mdrule-helper.md
tile.json

method-rule.mddocs/

Method Rule

The Method Rule prevents unsafe method calls like document.write(), insertAdjacentHTML(), and dynamic import() that can introduce security vulnerabilities. It validates function calls and ensures only safe arguments are passed to dangerous methods.

Capabilities

Rule Creation

Creates an ESLint rule that validates CallExpression, ImportExpression, and TaggedTemplateExpression nodes for unsafe method calls.

/**
 * Creates the method rule for ESLint
 * @param context - ESLint rule context with options and reporting capabilities
 * @returns ESLint rule visitor object with expression handlers
 */
const MethodRule = {
    meta: {
        type: "problem",
        docs: {
            description: "ESLint rule to disallow unsanitized method calls",
            category: "possible-errors",
            url: "https://github.com/mozilla/eslint-plugin-no-unsanitized/tree/master/docs/rules/method.md"
        },
        schema: [MethodRuleOptions, object]
    },
    create(context: ESLintRuleContext): MethodRuleVisitor
};

interface MethodRuleVisitor {
    CallExpression(node: CallExpressionNode): void;
    ImportExpression(node: ImportExpressionNode): void;
    TaggedTemplateExpression(node: TaggedTemplateExpressionNode): void;
}

Configuration Options

Configure rule behavior, escape functions, and method-specific settings.

interface MethodRuleOptions {
    /** Disable default rule checks */
    defaultDisable?: boolean;
    /** Configuration for allowed escape functions */
    escape?: {
        /** Array of allowed tagged template function names */
        taggedTemplates?: string[];
        /** Array of allowed escaping method names */
        methods?: string[];
    };
    /** Array of regex patterns to match object names */
    objectMatches?: string[];
    /** Array of parameter indices to validate */
    properties?: number[];
    /** Enable variable tracing to validate identifiers */
    variableTracing?: boolean;
}

// Note: The defaultDisable option is used to completely disable the default rule checks
// When true, only explicitly configured rules in the second options parameter will be active

Default Rule Checks

The rule checks these methods by default:

const defaultRuleChecks = {
    /** Check second parameter to .insertAdjacentHTML() */
    insertAdjacentHTML: {
        properties: [1]
    },
    /** Check first parameter of import() */
    import: {
        properties: [0]
    },
    /** Check first parameter to createContextualFragment() */
    createContextualFragment: {
        properties: [0]
    },
    /** Check first parameter to .write() on document objects */
    write: {
        objectMatches: ["document"],
        properties: [0]
    },
    /** Check first parameter to .writeln() on document objects */
    writeln: {
        objectMatches: ["document"],
        properties: [0]
    },
    /** Check first parameter to setHTMLUnsafe() */
    setHTMLUnsafe: {
        properties: [0]
    }
};

Expression Handling

The rule handles various JavaScript expression types for comprehensive security analysis:

/**
 * Validates CallExpression nodes against configured rules
 * @param ruleHelper - RuleHelper instance for validation
 * @param callExpr - The CallExpression to validate
 * @param node - The callee node being called
 */
function checkCallExpression(
    ruleHelper: RuleHelper, 
    callExpr: CallExpressionNode, 
    node: CalleeNode
): void;

/**
 * Validates ImportExpression nodes for dynamic imports
 * @param ruleHelper - RuleHelper instance for validation  
 * @param importExpr - The ImportExpression to validate
 */
function checkImport(ruleHelper: RuleHelper, importExpr: ImportExpressionNode): void;

// Supported callee node types with their handling behavior
type CalleeNode = 
    | IdentifierNode              // Simple function calls (checked if has arguments)
    | MemberExpressionNode        // Object method calls (checked if has arguments)
    | TSNonNullExpressionNode     // TypeScript non-null assertions (unwrapped)
    | TaggedTemplateExpressionNode // Tagged templates (converted to function calls)
    | TypeCastExpressionNode      // Flow type casts (unwrapped)
    | AssignmentExpressionNode    // Assignment expressions (checks right side)
    | ImportNode                  // Dynamic imports (always checked)
    | SequenceExpressionNode      // Comma operators (checks last expression)
    | TSAsExpressionNode          // TypeScript type assertions (ignored)
    | LogicalExpressionNode       // Logical expressions (ignored - see issue #62)
    | ConditionalExpressionNode   // Ternary operators (ignored)
    | ArrowFunctionExpressionNode // Arrow functions (ignored)
    | FunctionExpressionNode      // Function expressions (ignored)
    | SuperNode                   // Super calls (ignored)
    | CallExpressionNode          // Nested call expressions (ignored)
    | ThisExpressionNode          // This references (ignored)
    | NewExpressionNode           // Constructor calls (ignored)
    | TSTypeAssertionNode         // TypeScript type assertions (ignored)
    | AwaitExpressionNode;        // Await expressions (ignored - see issue #122)

Usage Examples:

// These method calls will trigger the rule
document.write(userInput);                    // Unsafe: direct user input
element.insertAdjacentHTML("beforeend", html); // Unsafe: unsanitized HTML
import(userControlledPath);                   // Unsafe: dynamic import

// These method calls are allowed
document.write("<h1>Static Title</h1>");      // Safe: literal
element.insertAdjacentHTML("beforeend", escapeHTML`<p>${data}</p>`); // Safe: tagged template
element.setHTML(content, { sanitizer: new Sanitizer() }); // Safe: Sanitizer API

// Object matching
document.write(content);                      // Checked: matches "document" 
myDoc.write(content);                        // Not checked: doesn't match pattern

// Parameter checking
insertAdjacentHTML("beforeend", content);     // Checks parameter 1 (content)
createContextualFragment(htmlString);         // Checks parameter 0 (htmlString)

Error Reporting

The rule reports unsafe method calls with descriptive messages:

// Basic unsafe method call
"Unsafe call to document.write for argument 0"

// With variable tracing details
"Unsafe call to insertAdjacentHTML for argument 1 (Variable 'html' reassigned with unsafe value at 25:12)"

// Unsupported expression types
"Error in no-unsanitized: Unexpected Callee. Please report a minimal code snippet to the developers at [GitHub URL]"

TaggedTemplateExpression Handling

The rule specially handles tagged template expressions by converting them to equivalent function calls:

// Tagged template: foo`bar${var1}${var2}`
// Converted to equivalent: foo(['bar', ''], var1, var2)

interface TaggedTemplateConversion {
    callee: TagNode;
    arguments: [TemplateStringsArray, ...ExpressionNode[]];
}