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

rule-helper.mddocs/

Rule Helper

The RuleHelper class provides the core validation logic shared between the property and method rules. It handles expression analysis, variable tracing, and security validation for unsafe code patterns.

Capabilities

RuleHelper Constructor

Creates a new RuleHelper instance with context and default rule configurations.

/**
 * Creates a RuleHelper instance for security validation
 * @param context - ESLint rule context with options and reporting
 * @param defaultRuleChecks - Default rule configuration object
 * @returns RuleHelper instance
 */
function RuleHelper(context: ESLintRuleContext, defaultRuleChecks: object): RuleHelper;

interface RuleHelper {
    context: ESLintRuleContext;
    ruleChecks: object;
    
    // Core validation methods
    allowedExpression(expression: any, escapeObject: EscapeConfiguration, details: ValidationDetails): boolean;
    isAllowedIdentifier(expression: IdentifierNode, escapeObject: EscapeConfiguration, details: ValidationDetails): boolean;
    isAllowedCallExpression(callee: CalleeNode, allowedSanitizers: string[]): boolean;
    
    // Method and property checking
    checkMethod(node: CallExpressionNode): void;
    checkProperty(node: AssignmentExpressionNode): void;
    
    // Utility methods
    normalizeMethodCall(node: CalleeNode): MethodCall;
    getCodeName(node: CalleeNode): string;
    shouldCheckMethodCall(node: CallExpressionNode, objectMatches: string[]): boolean;
    combineRuleChecks(defaultRuleChecks: object): object;
    reportUnsupported(node: any, reason: string, errorTitle: string): void;
}

Expression Validation

Validates expressions to determine if they contain safe or unsafe code patterns.

/**
 * Validates expression safety with recursive checking for complex expressions
 * @param expression - AST node to validate for safety
 * @param escapeObject - Configuration for allowed escape functions
 * @param details - Object to collect validation error details
 * @returns true if expression is safe, false otherwise
 */
allowedExpression(expression: any, escapeObject: EscapeConfiguration, details: ValidationDetails): boolean;

// Supported expression types
type SupportedExpression = 
    | "Literal"              // String/number literals (always safe)
    | "TemplateElement"      // Template literal text parts (safe)
    | "TemplateLiteral"      // Template literals with expressions
    | "TaggedTemplateExpression"  // Tagged template calls
    | "CallExpression"       // Function calls
    | "BinaryExpression"     // Binary operations like string concatenation
    | "TSAsExpression"       // TypeScript type assertions
    | "TypeCastExpression"   // Flow type casts
    | "Identifier";          // Variable references (with variable tracing)

interface ValidationDetails {
    message?: string;  // Detailed error message for reporting
}

Variable Tracing

Tracks variable declarations and assignments to validate identifier safety.

/**
 * Validates identifier safety through variable tracing
 * @param expression - Identifier node to validate
 * @param escapeObject - Configuration for allowed escape functions
 * @param details - Object to collect validation error details
 * @returns true if identifier is safe, false otherwise
 */
isAllowedIdentifier(expression: IdentifierNode, escapeObject: EscapeConfiguration, details: ValidationDetails): boolean;

// Variable tracing requirements
interface VariableTracingRules {
    // Only allow 'const' and 'let' declarations (not 'var')
    allowedDeclarationTypes: ["const", "let"];
    
    // Variable must be initialized with safe expression
    initializationRequired: boolean;
    
    // All subsequent assignments must also be safe
    assignmentValidation: boolean;
    
    // Function parameters are considered unsafe
    functionParametersAllowed: false;
}

Call Expression Validation

Validates function calls against allowed sanitizer lists.

/**
 * Checks if a function call is to an allowed sanitizer function
 * @param callee - Function being called
 * @param allowedSanitizers - Array of allowed function names
 * @returns true if call is to allowed sanitizer, false otherwise
 */
isAllowedCallExpression(callee: CalleeNode, allowedSanitizers: string[]): boolean;

// Default sanitizer functions
const VALID_ESCAPERS = ["Sanitizer.escapeHTML", "escapeHTML"];
const VALID_UNWRAPPERS = ["Sanitizer.unwrapSafeHTML", "unwrapSafeHTML"];

Method Call Analysis

Analyzes and normalizes method calls for consistent rule checking.

/**
 * Normalizes method call nodes to extract method and object names
 * @param node - Callable expression node
 * @returns Normalized method call information
 */
normalizeMethodCall(node: CalleeNode): MethodCall;

/**
 * Gets human-readable name for code expressions
 * @param node - Callable expression node
 * @returns String representation like "document.write" or "functionName"
 */
getCodeName(node: CalleeNode): string;

/**
 * Determines if method call should be checked based on object matching
 * @param node - Call expression to evaluate
 * @param objectMatches - Array of regex patterns for object names
 * @returns true if call should be checked, false to skip
 */
shouldCheckMethodCall(node: CallExpressionNode, objectMatches: string[]): boolean;

interface MethodCall {
    methodName: string;
    objectName?: string;
}

// Supported callee node types  
type CalleeNode = 
    | IdentifierNode           // Simple function calls
    | MemberExpressionNode     // Object method calls  
    | TSNonNullExpressionNode  // TypeScript non-null assertions
    | TaggedTemplateExpressionNode  // Tagged template literals
    | TypeCastExpressionNode   // Flow type casts
    | AssignmentExpressionNode // Assignment expressions
    | ImportNode               // Dynamic imports
    | SequenceExpressionNode   // Comma operators
    | TSAsExpressionNode;      // TypeScript type assertions

Rule Configuration

Merges default and user-provided rule configurations.

/**
 * Combines default rule checks with user configuration
 * @param defaultRuleChecks - Default rules for the plugin
 * @returns Merged rule configuration object
 */
combineRuleChecks(defaultRuleChecks: object): object;

// Configuration merging behavior
interface ConfigurationMerging {
    // User config takes precedence over defaults
    userConfigPrecedence: true;
    
    // Variable tracing enabled by default unless explicitly disabled
    defaultVariableTracing: true;
    
    // Default escape functions always included unless defaultDisable is true
    includeDefaultEscapeFunctions: boolean;
    
    // Per-rule customization with default fallbacks
    perRuleCustomization: boolean;
}

Validation Methods

Core methods for checking method calls and property assignments.

/**
 * Validates CallExpression nodes for unsafe method calls
 * @param node - Call expression to validate
 */
checkMethod(node: CallExpressionNode): void;

/**
 * Validates AssignmentExpression nodes for unsafe property assignments  
 * @param node - Assignment expression to validate
 */
checkProperty(node: AssignmentExpressionNode): void;

/**
 * Reports unsupported node types with helpful error messages
 * @param node - Unsupported AST node
 * @param reason - Human-readable reason for the error
 * @param errorTitle - Brief title for bug reports
 */
reportUnsupported(node: any, reason: string, errorTitle: string): void;

Usage Examples:

// Creating RuleHelper instance
const ruleHelper = new RuleHelper(context, {
    innerHTML: {},
    outerHTML: {}
});

// Expression validation
const escapeConfig = {
    taggedTemplates: ["escapeHTML", "html"],
    methods: ["sanitize", "escapeHTML"]
};

const details = {};
const isSafe = ruleHelper.allowedExpression(node.right, escapeConfig, details);

if (!isSafe && details.message) {
    context.report(node, `Unsafe assignment: ${details.message}`);
}

// Method call checking  
if (ruleHelper.shouldCheckMethodCall(callNode, ["document"])) {
    ruleHelper.checkMethod(callNode);
}

// Variable tracing example
const identifier = { type: "Identifier", name: "userContent" };
const isVariableSafe = ruleHelper.isAllowedIdentifier(identifier, escapeConfig, details);
// Will trace variable declaration and all assignments

Error Messages

The RuleHelper generates detailed error messages for different violation types:

// Property assignment errors
"Unsafe assignment to innerHTML"
"Unsafe assignment to innerHTML (Variable 'content' initialized with unsafe value at 15:8)"

// Method call errors  
"Unsafe call to document.write for argument 0"
"Unsafe call to insertAdjacentHTML for argument 1 (Variable 'html' reassigned with unsafe value at 25:12)"

// Variable tracing errors
"Variable 'data' declared as function parameter, which is considered unsafe. 'FunctionDeclaration' at 10:5"
"Variable 'content' initialized with unknown declaration 'ImportDeclaration' at 8:12"

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

Types

interface EscapeConfiguration {
    taggedTemplates?: string[];
    methods?: string[];
}

interface ESLintRuleContext {
    options: any[];
    sourceCode?: {
        getScope(node: any): Scope;
        getText(node: any): string;
    };
    getScope?(node: any): Scope;
    getSource?(node: any): string;
    report(node: any, message: string): void;
}

interface Scope {
    variableScope: {
        set: Map<string, VariableInfo>;
    };
}

interface VariableInfo {
    defs: VariableDefinition[];
    references: VariableReference[];
}

interface VariableDefinition {
    node: {
        type: string;
        init?: any;
        loc: {
            start: { line: number; column: number; };
        };
    };
    kind: "var" | "let" | "const";
}

interface VariableReference {
    isWrite(): boolean;
    writeExpr?: any;
}