两个角度看 web 安全
假如你是一个 hacker —— 攻击
跨站脚本攻击(XSS,Cross Site Scripting)
- 恶意脚本注入,
,浏览器将其当成自身 DOM 执行编译
- 主要利用了
- 作为开发者盲目信任用户提交的内容
- 前端工程师把用户提交的 string 直接转化为 DOM,例如 document.write、element.innerHTML = anyString 等
- XSS 的一些特点:
- 通常难以从 UI 上感知(暗地执行脚本)
- 窃取用户信息(cookie/token)
- 绘制 UI(例如弹窗),诱骗用户点击/填写表单
- XSS 攻击的分类
- 存储型 XSS(stored XSS)
- 恶意脚本被存在数据库中
- 访问页面 -> 读数据 -> 被攻击
- 危害最大,对全部用户可见
- 反射型 XSS(reflected XSS)
- 不涉及数据库
- 从 URL 上进行攻击
- 基于 DOM 的 XSS(DOM-based XSS)
- 不需要服务器的参与
- 恶意攻击的发起 + 执行,全部在浏览器中完成
- 与反射型 XSS 的区别在于完成注入脚本的地方:反射型在 server 端、DOM-based 在浏览器端
- Mutation-based XSS
- 利用了浏览器渲染 DOM 的特性(独特优化)
- 不同浏览器会有区别(按浏览器进行攻击)
- 存储型 XSS(stored XSS)
- 特点:
- 在用户不知情的前提下
- 利用用户权限(cookie)
- 构造指定 HTTP 请求,窃取或修改用户敏感信息
- 跨站伪造请求示例
文章图片
- 最常见的是利用链接发起 GET 请求(不局限于 GET 请求,构造 HTTP 请求即可)
- SQL 注入流程
文章图片
- 示例
// 读取请求字段直接以字符串的形式拼接 SQL 语句 public async renderForm(ctx){ const { username, form_id } = ctx.query; const result = await aql.query(` select a,b,c from table where username = ${username} and form_id = ${ from_id } `); ctx.body = renderForm(result); }// 攻击者 fetch("/api",{ method:"POST", headers:{ "Content-Type":"application/json" }, body:JSON.stringify({ username: "any; drop table tabelname; " }) })// 造成 select xxx from xxx drop table tablename 删库跑路
- 示例
- 严格上说不是 Injection,但是原理类似
- 请求用户自定义的callback URL
- web server 通常有内网访问权限
public async webhook(ctx){ // callback 可能是内网 url // e.g http://secret.com/get_employ_payrolls ctx.body = await fetch(ctx.query.callback); } // 访问 callback === 暴露内网信息
- 通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求导致请求挤压,进而产生雪崩效应
- ReDos:基于正则表达式的 Dos:重复匹配时
?
与no ?
满足“一个即可”与“尽量多”
const greedyRegExp = "/a+/"; // 有多少匹配多少 const nonGreedyRegExp = "/a+?/"// 有一个就可以 const str = "aaaaa"; console.log(str.match(greedyRegExp)[0])//aaaaa console.log(str.match(nonGreedyRegExp)[0])//a
- Distributed DoS:短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,产生雪崩效应,无法响应新请求
为什么产生?
- 明文传输
- 信息篡改不可知
- 对方身份未验证
文章图片
- 永远不信任用户的提交内容
- 不要将用户提交的内容直接转换成 DOM
文章图片
- 针对 XSS 的现成工具:
- 前端主流框架默认防御 XSS
- google-closure-library
- 在服务端有 Node.js 提供了 DOMPurify 帮助完成字符串转译防止 XSS
- 哪些源被认为是安全的
- 来自安全源的脚本可以执行,否则直接抛错
- 禁止 eval + inline script
- 设置方式:
- 服务器的响应头部
Content-Security-Policy: script-src 'self'// 同源 Content-Security-Policy: script-src 'self' https://domain.com//同源加 后面这个可以访问
- 浏览器 meta 标签
- 服务器的响应头部
- 因为其攻击方式是伪造请求,是异常来源,如果限制请求来源,也就限制了伪造请求
- 具体方法 CSRF —— token
文章图片
- iframe 攻击是同源请求,怎么解决
- 同源的发送请求没办法用 Origin 限制
- 方法:使用响应头部:
X-Frame-Options:deny/sameorigin
- 避免用户信息被携带:SameSite Cookie
- 从根源上解决了 CSRF,CSRF 是利用用户权限及 cookie,去伪造自己是该用户来进行恶意操作,如果攻击者无法获取到用户的 cookie 那就没用办法进行伪造了
- sameSite 限制的是 cookie domain、页面域名
- 如果是有 cookie 依赖第三方服务的(例如网站内嵌其他网站的播放器,不登录就没办法发弹幕),可以设置
Set-Cookie: SameSite=None; Secure;
- SameSite 与 CORS 对比
- SameSite 进行限制:Cookie 发送、domain 与页面域名
- CORS 类似白名单:资源读写 HTTP 请求、资源域名与页面域名、白名单
- 防御 CSRF 的正确方式 —— 编写中间件
- 针对 SQL Injection:找到项目中查询 SQL 的地方,使用 prepared statement
PREPARE q FROM 'SELECT user WHERE gender = ?'; SET @gender = 'female'; EXECUTE q USING @gender; DEALLOCATE PREPARE q;
- 除了 SQL
- 最小权限原则,不允许访问 sudo || root
- 建立允许名单 + 过滤,不允许进行 rm 这种系统操作
- 对 URL 类型参数进行协议、域名、ip 等限制,禁止访问内网
- Regex DoS:
- Code Review,避免贪婪模式
/(ab*)+/
- 代码扫描 + 正则性能测试
- 不要使用用户提供的正则
- Code Review,避免贪婪模式
- DDoS:
- 流量治理:负载均衡过滤、API 网关过滤、CDN 扛量
- 快速自动扩容
- 非核心服务降速
- 使用 HTTPS(HTTP + TLS)
文章图片
- 【Web 安全基础】HTTPS 的特性:
- 可靠性:加密,非明文传输
- 完整性:MAC 验证、禁止篡改、验证 hash
- 不可抵赖性:数字签名(CA 证书),进行身份验证 — 密码学
- SRI — Subresource Integrity:防止 CDN 静态资源被篡改
- Feature / Permission Policy:限制一个页面下,可以使用哪些功能
推荐阅读
- web网页模板|如此优秀的JS轮播图,写完老师都沉默了
- 接口|axios接口报错-参数类型错误解决
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- JavaScript|JavaScript — 初识数组、数组字面量和方法、forEach、数组的遍历
- JavaScript|JavaScript — call()和apply()、Date对象、Math、包装类、字符串的方法
- 前端|web前端dya07--ES6高级语法的转化&render&vue与webpack&export
- vue|Vue面试常用详细总结
- javascript|vue使用js-xlsx导出excel,可修改格子样式,例如背景颜色、字体大小、列宽等
- css|我用css精灵图拼接了自己的英文名字,不会还有人不知道精灵图技术吧()
- css|css三角的做法及其案例