Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/EtherDream/web-frontend-magic
#前端黑魔法# 整理
https://github.com/EtherDream/web-frontend-magic
Last synced: 2 months ago
JSON representation
#前端黑魔法# 整理
- Host: GitHub
- URL: https://github.com/EtherDream/web-frontend-magic
- Owner: EtherDream
- Created: 2019-11-14T07:09:23.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2021-10-16T11:49:30.000Z (over 3 years ago)
- Last Synced: 2024-08-02T18:43:40.575Z (6 months ago)
- Size: 401 KB
- Stars: 785
- Watchers: 27
- Forks: 33
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-github-star - web-frontend-magic
README
# Web 前端黑魔法
![](logo.png)
收集整理过去发表的 #前端黑魔法# 话题。
在此怀念和 [@zswang](https://github.com/zswang) 交流探讨前端黑魔法的时光。
# 2019
## HTTP 缓存更新
使用 fetch API 可更新 HTTP 缓存数据:
```js
fetch(url, {
cache: 'no-cache',
})
```设置 `cache` 选项为 `no-cache` 时,浏览器无视本地 HTTP 缓存,强制发起请求,并将最新内容覆盖已有缓存。
详细查看:https://www.cnblogs.com/index-html/p/http-cache-hotfix.html
## 检测浏览器代理
由于大部分 socks5 代理只转发数据,不转发 TCP 头,因此后端返回数据时附带一个特殊的 TCP 头,然后前端验证该头是否生效,即可推断否是存在代理。
例如后端下发 tcpwin=0 的控制信息,正常情况下前端收到后不会再往外发包,数据累计在协议栈缓冲区里。该特征可通过 WebSocket.bufferAmount 属性检测;而有代理的情况下,数据被累积在了代理服务的缓冲区,前端仍能往代理服务发包,缓冲区不会有累积。
演示:https://www.etherdream.com/proxy-detect/tcpwin.html
后端实现也很简单,NodeJS 实现 ws 服务,通过 setsockopt 给 socket 设置 mark,结合 tc 改包。
SHOW ME THE CODE
```js
// test.js
const {setsockopt} = require('sockopt')
const {WebSocketServer} = require('ws')
const wss = new WebSocketServer({port: 8080})wss.on('connection', (ws, req) => {
console.log(req.socket.remoteAddress + ':' + req.socket.remotePort)
setsockopt(req.socket, 1 /* SOL_SOCKET */, 36 /* SO_MARK */, 1 /* mark */)
ws.send('')
setTimeout(() => ws.terminate(), 2000)
})
``````bash
# reset tc rules
tc qdisc del dev eth0 root
tc qdisc replace dev eth0 root handle 1: htb# if mark = 1 then tcp.win = 0
tc filter add dev eth0 parent 1: u32 \
match mark 1 0xffffffff \
action pedit munge offset 34 u16 set 0 pipe \
csum ip and tcpnpm install ws sockopt
node test.js
```HTTPS 同样支持。但不能运行在 CloudFlare 之类的服务后面,否则 TCP 特殊头就丢失了。如果网络会自动重算 checksum,那么 `pipe csum ip and tcp` 可省略。
## 发送 UDP 无状态包
WebRTC 可发送 UDP 数据,但必须先经过握手等环节。有没有办法,第一个包就能携带自定义数据?
WebRTC 传统用法是 P2P 通信,双方先通过 STUN 服务查询自己的公网地址并完成打洞,然后交换 SDP 等信息,相互连接。
但如果是 C/S 通信,服务端地址已知,那么客户端可跳过打洞步骤,直接虚构一份 SDP,把对方地址填进去就可以发包了。SDP 中的 `ice-ufrag` 会明文出现在 UDP 包中。该参数接受字母、数字和 #+-/=_ 共 68 种字符,最大长度 256,因此可携带一定量的信息到服务端。
----
一个比较有意义的应用场景是端口敲门:目标服务器(任意服务都可以)默认禁止所有 IP,通过传送门页面给它发 UDP 敲门包。服务器收到预期的 UDP 后,将该包的源 IP 加入白名单。
演示:https://www.etherdream.com/port-knocking/
点击按钮之前无法访问目标服务,点击按钮之后就可以访问了。使用这个方案,即可抵挡后台管理服务的暴力破解,以及其他的扫描流量。也可以用于 DDOS/CC 防御(比如用 GitHub Pages 这种打不垮的页面做传送门)
![image](https://user-images.githubusercontent.com/1072787/130002091-ff85caad-7866-423c-b41e-a84861553e52.png)
![image](https://user-images.githubusercontent.com/1072787/130002182-f14dfb40-400d-4e1f-ac4d-13d10a1c1432.png)
更多参考:https://www.cnblogs.com/index-html/p/js-port-knocking.html
## 获取往返数据包的 TTL
后端获取用户的 TTL 很容易,但在浏览器上获取后端的 TTL 很麻烦。
不过有个黑科技,可以让后端返回的包反弹回服务器 —— 只要前端在收到数据前释放 socket,之后操作系统找不到目标端口,就会发送「ICMP 端口不可到达」给服务器,其中封装了返回包的头部信息。
演示:https://www.etherdream.com/test/stunex.html
详细参考:https://www.cnblogs.com/index-html/p/js-get-round-trip-ttl.html
# 更早的
下面大多从 weibo 搬运过来,账号 @EtherDream 去年被禁言,以后在此更新。表情符已替换成 ~(大部分可脑补成狗头)
[2018.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2018.md)
[2017.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2017.md)
[2016.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2016.md)
[2015.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2015.md)
[2014.md](https://github.com/EtherDream/web-frontend-magic/blob/master/2014.md)