├── logo.png
├── 2014.md
├── README.md
├── 2017.md
├── 2016.md
├── 2015.md
└── 2018.md
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EtherDream/web-frontend-magic/HEAD/logo.png
--------------------------------------------------------------------------------
/2014.md:
--------------------------------------------------------------------------------
1 | # 2014-12-3
2 |
3 | ```js
4 | 1767707668033969..toString(36) // "helloworld"
5 | ```
6 |
7 | ---
8 |
9 | 卖萌的语法~
10 |
11 | ```js
12 | 0.==.0
13 | ```
14 |
15 |
16 | # 2014-11-13
17 |
18 | Hack 小技巧:检测 console 是否被打开
19 |
20 | Demo: https://www.etherdream.com/FunnyScript/console_detect/
21 |
22 | 
23 |
24 | 
25 |
26 | 发现有程序猿在调试,哥就封了它~
27 |
28 |
29 |
30 | # 2014-8-16
31 |
32 | 最新原创: 《HttpOnly Cookie 隐私嗅探》
33 |
34 | https://fex.baidu.com/blog/2014/08/sensitive-data-sniffer/
35 |
36 |
37 |
38 | # 2014-6-20
39 |
40 | 《XSS 前端防火墙》系列
41 |
42 | 
43 |
44 | https://fex.baidu.com/blog/2014/06/xss-frontend-firewall-1/
45 |
46 | https://fex.baidu.com/blog/2014/06/xss-frontend-firewall-2/
47 |
48 | https://fex.baidu.com/blog/2014/06/xss-frontend-firewall-3/
49 |
50 | https://fex.baidu.com/blog/2014/06/xss-frontend-firewall-4/
51 |
52 | https://fex.baidu.com/blog/2014/06/xss-frontend-firewall-5/
53 |
54 | Demo: https://www.etherdream.com/FunnyScript/csp/battle/
55 |
56 | > 该项目除了监控 XSS 之外,还可用于运营商/浏览器插件的流量劫持监控。过些时候开源~
57 |
58 |
59 | # 2014
60 |
61 | 微博账号 @EtherDream 发布的已全部在此,之后更新在其他论坛发布的...
62 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Web 前端黑魔法
2 |
3 | 
4 |
5 | 收集整理过去发表的 #前端黑魔法# 话题。
6 |
7 | 在此怀念和 [@zswang](https://github.com/zswang) 交流探讨前端黑魔法的时光。
8 |
9 |
10 | # 2019
11 |
12 | ## HTTP 缓存更新
13 |
14 | 使用 fetch API 可更新 HTTP 缓存数据:
15 |
16 | ```js
17 | fetch(url, {
18 | cache: 'no-cache',
19 | })
20 | ```
21 |
22 | 设置 `cache` 选项为 `no-cache` 时,浏览器无视本地 HTTP 缓存,强制发起请求,并将最新内容覆盖已有缓存。
23 |
24 | 详细查看:https://www.cnblogs.com/index-html/p/http-cache-hotfix.html
25 |
26 |
27 | ## 检测浏览器代理
28 |
29 | 由于大部分 socks5 代理只转发数据,不转发 TCP 头,因此后端返回数据时附带一个特殊的 TCP 头,然后前端验证该头是否生效,即可推断否是存在代理。
30 |
31 | 例如后端下发 tcpwin=0 的控制信息,正常情况下前端收到后不会再往外发包,数据累计在协议栈缓冲区里。该特征可通过 WebSocket.bufferAmount 属性检测;而有代理的情况下,数据被累积在了代理服务的缓冲区,前端仍能往代理服务发包,缓冲区不会有累积。
32 |
33 | 演示:https://www.etherdream.com/proxy-detect/tcpwin.html
34 |
35 | 后端实现也很简单,NodeJS 实现 ws 服务,通过 setsockopt 给 socket 设置 mark,结合 tc 改包。
36 |
37 |
38 | SHOW ME THE CODE
39 |
40 | ```js
41 | // test.js
42 | const {setsockopt} = require('sockopt')
43 | const {WebSocketServer} = require('ws')
44 | const wss = new WebSocketServer({port: 8080})
45 |
46 | wss.on('connection', (ws, req) => {
47 | console.log(req.socket.remoteAddress + ':' + req.socket.remotePort)
48 | setsockopt(req.socket, 1 /* SOL_SOCKET */, 36 /* SO_MARK */, 1 /* mark */)
49 | ws.send('')
50 | setTimeout(() => ws.terminate(), 2000)
51 | })
52 | ```
53 |
54 | ```bash
55 | # reset tc rules
56 | tc qdisc del dev eth0 root
57 | tc qdisc replace dev eth0 root handle 1: htb
58 |
59 | # if mark = 1 then tcp.win = 0
60 | tc filter add dev eth0 parent 1: u32 \
61 | match mark 1 0xffffffff \
62 | action pedit munge offset 34 u16 set 0 pipe \
63 | csum ip and tcp
64 |
65 | npm install ws sockopt
66 | node test.js
67 | ```
68 |
69 | HTTPS 同样支持。但不能运行在 CloudFlare 之类的服务后面,否则 TCP 特殊头就丢失了。如果网络会自动重算 checksum,那么 `pipe csum ip and tcp` 可省略。
70 |
71 |
72 |
73 | ## 发送 UDP 无状态包
74 |
75 | WebRTC 可发送 UDP 数据,但必须先经过握手等环节。有没有办法,第一个包就能携带自定义数据?
76 |
77 | WebRTC 传统用法是 P2P 通信,双方先通过 STUN 服务查询自己的公网地址并完成打洞,然后交换 SDP 等信息,相互连接。
78 |
79 | 但如果是 C/S 通信,服务端地址已知,那么客户端可跳过打洞步骤,直接虚构一份 SDP,把对方地址填进去就可以发包了。SDP 中的 `ice-ufrag` 会明文出现在 UDP 包中。该参数接受字母、数字和 #+-/=_ 共 68 种字符,最大长度 256,因此可携带一定量的信息到服务端。
80 |
81 | ----
82 |
83 | 一个比较有意义的应用场景是端口敲门:目标服务器(任意服务都可以)默认禁止所有 IP,通过传送门页面给它发 UDP 敲门包。服务器收到预期的 UDP 后,将该包的源 IP 加入白名单。
84 |
85 | 演示:https://www.etherdream.com/port-knocking/
86 |
87 | 点击按钮之前无法访问目标服务,点击按钮之后就可以访问了。使用这个方案,即可抵挡后台管理服务的暴力破解,以及其他的扫描流量。也可以用于 DDOS/CC 防御(比如用 GitHub Pages 这种打不垮的页面做传送门)
88 |
89 | 
90 |
91 | 
92 |
93 | 更多参考:https://www.cnblogs.com/index-html/p/js-port-knocking.html
94 |
95 |
96 | ## 获取往返数据包的 TTL
97 |
98 | 后端获取用户的 TTL 很容易,但在浏览器上获取后端的 TTL 很麻烦。
99 |
100 | 不过有个黑科技,可以让后端返回的包反弹回服务器 —— 只要前端在收到数据前释放 socket,之后操作系统找不到目标端口,就会发送「ICMP 端口不可到达」给服务器,其中封装了返回包的头部信息。
101 |
102 | 演示:https://www.etherdream.com/test/stunex.html
103 |
104 | 详细参考:https://www.cnblogs.com/index-html/p/js-get-round-trip-ttl.html
105 |
106 |
107 | # 更早的
108 |
109 | 下面大多从 weibo 搬运过来,账号 @EtherDream 去年被禁言,以后在此更新。表情符已替换成 ~(大部分可脑补成狗头)
110 |
111 | [2018.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2018.md)
112 |
113 | [2017.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2017.md)
114 |
115 | [2016.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2016.md)
116 |
117 | [2015.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2015.md)
118 |
119 | [2014.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2014.md)
--------------------------------------------------------------------------------
/2017.md:
--------------------------------------------------------------------------------
1 |
2 | # 2017-12-29
3 |
4 | 元旦期间,相信大家都被微信小游戏刷屏了,各种玩法攻略铺天盖地。当得知这是用 JS 开发时,立马想把过去写的 JS 游戏都翻新一遍。于是打开小游戏的官网,查看开发文档。
5 |
6 | 然而遗憾的是,小游戏虽然是用 JS 写的,但它并非运行在浏览器环境里,因此和 HTML 并不兼容。此外,在官网文档上,还看见一条奇葩的规则:
7 |
8 | ```
9 | 2.与小程序一样,小游戏每次发布需要经过审核。我们在小程序和小游戏中都移除了动态执行代码的能力,包括以下调用方式:
10 | (1)eval 函数
11 | (2)setTimeout、setInterval 函数第一个参数传入代码字符串执行
12 | (3)使用 Function 传入字符串构造函数
13 | (4)使用 GeneratorFunction 传入字符串构造生成器函数
14 | ```
15 |
16 | 咋一看貌似有些道理,要是开放 eval 的话,代码可以从网络上更新,就能绕过官方审核了。
17 |
18 | 但是,开发者若真想动态执行,那根本就是拦不住的 —— 在代码里藏一个虚拟机不就可以了吗。之前我们探讨[《使用虚拟机混淆 JavaScript 代码》](https://www.cnblogs.com/index-html/p/use_vm_protect_js.html)时,就讲解了 JS 虚拟机的概念,让程序根据不同的数据,执行不同的操作。虽然性能不高,但用于简单临时的场合,还是没问题的。
19 |
20 | 这时冒出个想法:要是能把性能优化得足够好的话,是不是可以让整个小游戏都由虚拟指令实现,这样程序只需发布一次就再也不用审核了呢?
21 |
22 | 于是开始探索,一个不用 eval、而是由 JS 自我驱动的图灵机,性能最高能达到多少。
23 |
24 | > 某些简单的场合性能可达 100%!细节分享: https://github.com/EtherDream/web-frontend-magic/issues/3
25 |
26 |
27 |
28 | # 2017-3-13
29 |
30 | 周末研究 WebGL2 时写了个 SHA256 PoW 的挖矿原型~
31 |
32 | 
33 |
34 | Demo: https://www.etherdream.com/FunnyScript/glminer/glminer.html
35 |
36 | 用笔记本自带的核显每秒可以 3000 万次左右的 SHA256 计算(2013 款 MBP)。如果有独显就更快了,试了下 Titan X 能跑出每秒 4.6 亿 hash/s
37 |
38 | 当然,即便能 100% 利用 GPU 也远没法和矿机比,更何况 WebGL 只有 50% 左右的效率。不过用于 XSS 分布式密码破解倒是不错,改天写一个破解 WPA2 的算法~
39 |
40 |
41 |
42 | # 2017-3-8
43 |
44 | WebGL 2.0 API Quick Reference Guide
45 |
46 | 
47 |
48 | https://www.khronos.org/files/webgl20-reference-guide.pdf
49 |
50 | WebGL2 终于支持整数和位运算了!
51 |
52 | 曾有人试图用 [WebGL1 挖矿](https://github.com/derjanb/hamiyoca),由于不支持整数和位运算,只能靠浮点计算模拟,效率大大的低~
53 |
54 |
55 |
56 | # 2017-3-6
57 |
58 | 5.4M 的 JS 文件。。。打开控制台就卡了十几秒,点 format 卡了半分钟~ 不过运行倒是很流畅
59 |
60 | 
61 |
62 | 
63 |
64 | 期待 WebAssembly 快点普及吧~
65 |
66 |
67 |
68 | # 2017-3-5
69 |
70 | 写了个「阻止 XSS 自动发表留言」的案例,可以减缓蠕虫传播。试试你能不能绕过它~
71 |
72 | Demo: https://www.etherdream.com/FunnyScript/anti-xssworm/
73 |
74 | 原理很简单,用一个「跨源」的 iframe 充当按钮,起到 JS 隔离效果。另外,数据也通过 iframe 提交,后端通过 referer 即可判断是不是 iframe 提交的。
75 |
76 | 当然,这个方案阻止不了 clickjacking。
77 |
78 | > 详解:https://www.cnblogs.com/index-html/p/anti_xss_worm.html
79 |
80 |
81 |
82 | # 2017-3-2
83 |
84 | 经常看到有人讨论如果不能用 HTTPS 只能用 HTTP 页面,该如何对抗中间人劫持的问题。
85 |
86 | 其实可以用个黑科技缓解:浏览器强缓存。比如用 HTML5 AppCache、max-age 等将页面强缓存,子资源则通过 JS 加密传输。
87 |
88 | 这样可把风险降到首次访问上,以后就算遇到不安全的网络,访问入口页面仍是缓存里的内容(除非第一次访问时就被劫持,否则仍是之前遗留的安全内容)。
89 |
90 | 这种方案类似 TOFU(Trust on First Use,信任首次使用)的思想。
91 |
92 |
93 |
94 | # 2017-3-1
95 |
96 | 都忘了 `