MST

星途 面试题库

面试题:JavaScript 类和原型安全防护之专家题

假设你正在开发一个大型的 JavaScript 应用,其中有多个模块会涉及到类和原型的使用。现在要求设计一套完整的安全防护机制,确保不同模块间的类和原型不会相互干扰,避免原型污染,并且能有效防止恶意代码利用类和原型漏洞进行攻击,详细描述你的设计思路和关键实现代码。
34.6万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 模块封装:使用 ES6 模块系统,每个模块都有自己独立的作用域,避免全局变量污染。这样不同模块的类和原型不会在全局作用域下相互干扰。
  2. 冻结对象:对于不希望被修改的类和原型,使用 Object.freeze 方法。冻结后的对象不能添加新属性,不能修改现有属性,也不能删除属性,从而防止恶意代码对其进行修改导致原型污染。
  3. 严格模式:在模块中使用严格模式('use strict';),严格模式会对一些潜在不安全或不符合规范的操作抛出错误,例如给不可写属性赋值、使用未声明变量等,有助于发现潜在的恶意代码行为。
  4. 验证输入:在涉及到使用外部输入来操作类和原型时,对输入进行严格的验证。确保输入的数据类型和内容符合预期,防止恶意数据导致原型污染或其他安全漏洞。
  5. 不可枚举属性:将一些关键属性设置为不可枚举(Object.defineProperty 时设置 enumerable: false),这样恶意代码通过 for...in 等枚举操作无法访问到这些属性,降低被攻击的风险。

关键实现代码

  1. 模块封装示例
// module1.js
export class MyClass1 {
    constructor() {
        this.property1 = 'value1';
    }
}

// module2.js
export class MyClass2 {
    constructor() {
        this.property2 = 'value2';
    }
}
  1. 冻结对象示例
class MySecureClass {
    constructor() {
        this.someProperty = 'initial value';
    }
}
Object.freeze(MySecureClass.prototype);
const instance = new MySecureClass();
// 以下操作在严格模式下会报错
// instance.__proto__.newProperty = 'attempted malicious addition'; 
  1. 严格模式使用
// 整个模块使用严格模式
'use strict';
class MyClass {
    constructor() {
        // 这里的代码遵循严格模式规则
    }
}
  1. 验证输入示例
class User {
    constructor(name) {
        if (typeof name!=='string' || name.length === 0) {
            throw new Error('Invalid name input');
        }
        this.name = name;
    }
}
  1. 设置不可枚举属性示例
class SomeClass {
    constructor() {
        this.publicProperty = 'visible';
    }
}
Object.defineProperty(SomeClass.prototype, 'privateProperty', {
    value: 'not enumerable',
    enumerable: false
});
const obj = new SomeClass();
for (let key in obj) {
    console.log(key); // 不会输出 'privateProperty'
}