收集整理过去发表的 #前端黑魔法# 话题。
在此怀念和 @zswang 交流探讨前端黑魔法的时光。
原文链接: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
~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/
当然,用 GPU 挖矿意义不大,网页还是适合挖 CPU 算法的币。
不过 GPU 这种通用的硬件,显然更适合破解密码,比如 WiFi 密码。Shader 好好优化下,破解速度可以达到 hashcat 一半左右。论坛 XSS 每个用户贡献几分钟,还是不错的~ WiFi 破解后,还可以劫持流量植入 JS,于是又可以增加一些算力~
关于 Service Worker 各种玩法,可参考 https://github.com/etherdream/sw-sec
2018-9-28
思考题:如何实现一个网页版的 CPU 跑分程序,并且带有用户排行榜功能。(重点是确保用户不易作弊,比如自定义提交成绩;以及不能使用多核 CPU 甚至 GPU 来加速,只拼单核性能)
哪些密码学算法是无法利用多线程加速的,并且能在网页里高效率运行?
2018-9-13
《大航海时代 2》风格的 Google Map
Demo: https://jsfiddle.net/84j1cvt9/29/
2018-9-12
Win1.0 的 calc.exe(非原创)
Demo: https://classicreload.com/Windows-1-01.html
Win1.0 只比 Win10 差一点而已~
2018-9-11
直到现在,仍有相当多的用户甚至开发者都不知道【允许三方 Cookie】存在多大的危险~
一句话概况【允许三方 Cookie】的危险:在不安全的网络环境下,访问任何一个 HTTP 页面,各大网站 Cookie 可能瞬间被中间人拿到。
原理说过很多次了,不再解释
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)
当然这个是上古时代的黑魔法了,稍懂前端的都知道怎么实现。所以这里只问最短的实现~
目前想到的是 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 就无法使用了~~~
如果真遇到项目文件夹之外有 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 的箭头图标。
不过想要一次成功,还是需要些小技巧的,毕竟刚打开 DevTool 的时候还是会触发 debugger 断下来的:
所以正确的打开方式,应该先随便开一个网页,打开 DevTool 禁用断点:
然后再打开想要访问的网页,这时 debugger 就不会触发了:
2018-5-21
大写的 αß 服不服~
'αß'.toUpperCase() // "ΑSS"
类似的还有 'ffi'.toUpperCase() === 'FFI'。然而 '嬲'.toUpperCase() !== '男女男' ~
2018-5-21
随着 JS 引擎优化能力的提升,越来越多的性能黑魔法将会消失~
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
相册里翻到个上古时代用
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。