开发者社区> 问答> 正文

【经典干货】Web 前端黑魔法

image.png

收集整理过去发表的 #前端黑魔法# 话题。

在此怀念和 @zswang 交流探讨前端黑魔法的时光。

展开
收起
茶什i 2019-12-02 14:34:20 2216 0
1 条回答
写回答
取消 提交回答
  • 原文链接:https://developer.aliyun.com/article/736947

    2019 整理中...

    下面大多从 weibo 搬运过来,账号 @EtherDream 去年被禁言,以后在此更新。表情符已替换成 ~(大部分可脑补成狗头)

    2018-12-19 有人说,能用 const 的时候尽量用 const。所以,循环因子也可以。。。

    for (const i of range(0, 5)) {
      console.log(i)  // 0, 1, 2, 3, 4
    }
    
    function* range(beg, end, step = 1) {
      for (let i = beg; i < end; i += step)
        yield i
    }
    

    有没有 Python 的感觉~

    2018-11-19 思考题:如何获取闭包内 key 变量的值:

    // 挑战目标:获取 key 的值
    (function() {
      // 一个内部变量,外部无法获取
      var key = Math.random()
    
      console.log('[test] key:', key)
    
      // 一个内部函数
      function internal(x) {
        return x
      }
    
      // 对外暴露的函数
      apiX = function(x) {
        try {
          return internal(x)
        } catch (err) {
          return key
        }
      }
    })()
    
    // 你的代码写在此处:
    // ...
    

    答案:https://github.com/EtherDream/web-frontend-magic/issues/1

    2018-11-19 思考题:检测隐形人是否存在

    // 挑战目标:检测 Math 是否被代理
    if (Math.random() < 0.5) {
      console.log('hooked')
    
      self.Math = new Proxy(Math, {
        get(obj, prop) {
          return obj[prop]
        }
      })
    }
    
    // 你的代码写在此处:
    // 如果控制台有显示 hooked,那么你输出 true,反之 false
    // ...
    

    Demo: https://jsfiddle.net/k0nupd58/

    答案有多个,但有一种特别巧妙,可以参考「如何获取闭包内 key 变量的值」的思路。

    2018-10-26 点一下,CPU 开始咆哮

    Demo: https://www.etherdream.com/FunnyScript/cpu-hog/

    该页面创建 1000 个 Service Worker 消耗大量 CPU。即使关闭页面,它们仍在后台运行。想尝试的话务必在隐身模式中打开,感觉卡了就可以关闭了。

    2018-10-18 一种统计 key 的个数,无需使用判断的写法:

    const map = {}
    const str = 'hello world'
    
    str.split('').forEach(key => {
      map[key] = -~map[key]
    })
    
    console.log(map)
    // {" ": 1, d: 1, e: 1, h: 1, l: 3, o: 2, r: 1, w: 1}```
    Demo: [https://jsbin.com/lumexovida/edit?js,console,output](https://jsbin.com/lumexovida/edit?js,console,output)
    
    > ~i = -(i + 1),~undefined = -1  
    
    
    **2018-10-17**
    自从 Chrome 69 支持 OffscreenCanvas API 后,终于能在 Service Worker 里调用 GPU 资源了~ 所以用户关闭网页后,XSS 还可以继续使用 100% CPU 和 GPU 资源几分钟时间~
    
    拿之前的 SHA256 PoW 改了下貌似可行~
    
    Demo: [https://www.etherdream.com/FunnyScript/glminer/sw-miner/](https://www.etherdream.com/FunnyScript/glminer/sw-miner/)
    
    ![image.png](https://ucc.alicdn.com/pic/developer-ecology/574ade3a3c7e46f780019d0566e30e42.png)
    
    
    ![image.png](https://ucc.alicdn.com/pic/developer-ecology/a9d7a9e9ded04d9c86f1d97156734ab0.png) 
    
    ![image.png](https://ucc.alicdn.com/pic/developer-ecology/fce92786f484432bab8a059cc668cf78.png)
    
    当然,用 GPU 挖矿意义不大,网页还是适合挖 CPU 算法的币。
    
    不过 GPU 这种通用的硬件,显然更适合破解密码,比如 WiFi 密码。Shader 好好优化下,破解速度可以达到 hashcat 一半左右。论坛 XSS 每个用户贡献几分钟,还是不错的~ WiFi 破解后,还可以劫持流量植入 JS,于是又可以增加一些算力~
    
    关于 Service Worker 各种玩法,可参考 [https://github.com/etherdream/sw-sec](https://github.com/etherdream/sw-sec)
    
    **2018-9-28**
    思考题:如何实现一个网页版的 CPU 跑分程序,并且带有用户排行榜功能。(重点是确保用户不易作弊,比如自定义提交成绩;以及不能使用多核 CPU 甚至 GPU 来加速,只拼单核性能)
    
    > 哪些密码学算法是无法利用多线程加速的,并且能在网页里高效率运行?  
    
    
    **2018-9-13**
    《大航海时代 2》风格的 Google Map
    
    Demo: [https://jsfiddle.net/84j1cvt9/29/](https://jsfiddle.net/84j1cvt9/29/)
    
    ![image.png](https://ucc.alicdn.com/pic/developer-ecology/e3dc882210e647f2aee1911d33f8d3cf.png)
    
    
    ![image.png](https://ucc.alicdn.com/pic/developer-ecology/7bbec6f9c2634d90ba7588536eba2dfe.png)
    
    
    **2018-9-12**
    Win1.0 的 calc.exe(非原创)
    
    ![image.png](https://ucc.alicdn.com/pic/developer-ecology/f23ff73ddfb343ba96df796ea4024d51.png)
    
    
    Demo: [https://classicreload.com/Windows-1-01.html](https://classicreload.com/Windows-1-01.html)
    
    > Win1.0 只比 Win10 差一点而已~  
    
    
    **2018-9-11**
    直到现在,仍有相当多的用户甚至开发者都不知道【允许三方 Cookie】存在多大的危险~
    
    一句话概况【允许三方 Cookie】的危险:在不安全的网络环境下,访问任何一个 HTTP 页面,各大网站 Cookie 可能瞬间被中间人拿到。
    
    ![image.png](https://ucc.alicdn.com/pic/developer-ecology/3d43b329b1a14ca6a557b3c811015f1e.png)
    
    
    > 原理说过很多次了,不再解释  
    
    
    **2018-9-7**  
    出个思考题:尝试读取 obj 中那个带随机数的隐藏属性
    
    

    var obj = {}

    Object.defineProperty(obj, '$' + Math.random(), { get: () => alert('You win!'), enumerable: false, })

    // write code here:```
    Demo: https://jsfiddle.net/2c358wxp/

    有多个答案

    2018-8-17
    有什么场合,必须使用 ES6 的 Reflect?

    答案:https://github.com/EtherDream/web-frontend-magic/issues/2

    2018-8-1 思考题:用最少的字符实现下图效果。

    (鼠标悬浮在超链接上,状态栏显示的是网站 A,但点击进入的却是网站 B)

    image.png

    image.png

    当然这个是上古时代的黑魔法了,稍懂前端的都知道怎么实现。所以这里只问最短的实现~

    目前想到的是 55 字符(包括目标域名):https://www.etherdream.com/FunnyScript/statusbar_spoof_2.html

    讲解:超链接和 location 很像,都有 href、host 等 URL 属性。不少人以为只有 href 属性可赋值,事实上其他属性也可以。

    比如想把当前页面从 http 跳转到 https,只需修改 protocol 即可:

    location.protocol = 'https:'
    

    另外 HTML 内联事件默认套有 with(this),所以可省略 this. 这几个字符。

    2018-7-27
    一种检测 HTTPS 中间人降级攻击的猥琐思路~

    <script>
     if ('https://a.com'.startsWith('http:')) {
       // send_log('SSLStrip detected')
     }
    </script>
    

    在公司的脚本上尝试后发现竟然有不少日志,看来这类攻击目前还是存在的。。。

    HTTPS 中间人降级攻击,本质上就是把流量中的 https:// 替换成 http://。所以又称 -1s 攻击~

    2018-7-26 由于大部分用户都不会开启浏览器 Do Not Track,因此少数开了的用户反而成了另类,被用于浏览器指纹特征了。。。

    2018-7-20 思考题:在 JS 中用 0 0 0 0 四个常量计算 24。只能用符号,表达式越短越好~

    目前已知最短的答案 14 字符。https://jsfiddle.net/qLo2jg7x/

    2018-6-6 BitInt 出现后,不用死循环也能实现 CPU 100% 的效果了。一个 2 层幂塔就能卡死浏览器~

    9n ** 9n ** 9n > 0
    

    为什么这里要加 > 0 的判断,因为

    9 ^ 9 ^ 9 ≈ 4.28 x 10^369693099
    

    这个数字,光是位数就有 369,693,099 之多,相当于控制台要输出一个 300 多兆的字符串!所以为了不在输出时卡死,于是加了个判断。

    (事实上基本等不到字符串输出那步)

    2018-5-22
    nodejs 恶作剧:给系统创建一个叫 node_modules 的用户,然后 npm install 就无法使用了~~~

    image.png

    image.png

    如果真遇到项目文件夹之外有 node_modules 的话,只要在 npm install 时加上参数 --prefix path 就可以强制指定 node_modules 的路径。

    2018-5-21 之前遇到个网站 WAF 的 JS 脚本,代码经过多次动态混淆。

    为了防止被人调试,前端不断执行 debugger 指令,然后检测执行用时 —— 如果控制台开着,debugger 指令会触发断点,用时显然高出平常。于是 JS 会给后端发送日志,然后 IP 就被网站 ban 了。

    setInterval(function() {
      var t1 = Date.now();
      debugger;
      var t2 = Date.now();
      if (t2 - t1 > 100) {
        console.log('debug detected');
        // send_log('ban this ip');
      }
    }, 500);
    

    简单演示:https://codepen.io/anon/pen/rvPYxR?editors=0010

    当然,在经过几次 IP 更换后,很快就摸索出了一个超级简单的规避方案。猜猜是如何实现~

    其实非常简单,禁用调试器断点功能就可以,比如 Chrome DevTool 的箭头图标。

    image.png

    不过想要一次成功,还是需要些小技巧的,毕竟刚打开 DevTool 的时候还是会触发 debugger 断下来的:

    image.png

    所以正确的打开方式,应该先随便开一个网页,打开 DevTool 禁用断点:

    image.png

    然后再打开想要访问的网页,这时 debugger 就不会触发了:

    image.png

    2018-5-21 大写的 αß 服不服~

    'αß'.toUpperCase()    // "ΑSS"
    

    类似的还有 'ffi'.toUpperCase() === 'FFI'。然而 '嬲'.toUpperCase() !== '男女男' ~

    2018-5-21 随着 JS 引擎优化能力的提升,越来越多的性能黑魔法将会消失~

    image.png

    image.png

    2018-5-15 思考题:定义 x 使得满足条件判断,字数越少越好。目前我的答案是 28 个字符,看看有没有更短的~

    const x = _______
    const win = ('a' in x) && !('a' in x)
    console.log(win)    // true
    

    答案:https://jsfiddle.net/r6gk1ob8/

    2018-5-14 思考题:有些 JS 代码混淆后,会变成 eval(一大坨代码) 的形式。当然解密也非常容易,把 eval 换成 console.log 就能原形毕露。

    下面请思考,如何在「一大坨代码」中加入陷阱,跟踪有哪些人把 eval 换成了其他的函数?

    答案:https://codepen.io/anon/pen/odMbBX?editors=0010

    (eval 换成 console.log 即可触发陷阱)

    2018-5-14 如何使用 JS 缓解网站 DDOS 的攻击?

    https://yq.aliyun.com/articles/236585

    大致原理:网页多用强缓存(目前是 Service Worker),发生故障时可毫秒级切换流量到 N 个后备节点。网站被打垮也只影响新用户,老用户照样可以流畅访问~

    当然这其中细节问题很多,以后会在 https://github.com/EtherDream/js-anti-ddos 中讨论。

    2018-5-8 相册里翻到个上古时代用

    2019-12-02 17:58:03
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Vue.js 在前端服务化上的探索与实践 立即下载
阿里文娱大前端技术实践 立即下载
前端代码是怎样智能生成的 立即下载