所以平时开发时最好避免使用 dangerouslySetInnerHTML , 如果不得不使用的话 , 前端或服务端必须对输入进行相关验证 , 例如对特殊输入进行过滤、转义等处理 。前端这边处理的话 , 推荐使用白名单过滤 (https://jsxss.com/zh/index.html) , 通过白名单控制允许的 HTML 标签及各标签的属性 。
通过用户提供的对象来创建 React 组件举个例子:
// 用户的输入const userProvidePropsString = `{"dangerouslySetInnerHTML":{"__html":"<img onerror='alert("xss");' src=https://www.isolves.com/it/aq/sj/2020-09-24/'empty.png' />"}}"`;// 经过 JSON 转换const userProvideProps = JSON.parse(userProvidePropsString);// userProvideProps = {// dangerouslySetInnerHTML: {// "__html": ``// }// };render() { // 出于某种原因解析用户提供的 JSON 并将对象作为 props 传递 return }
这段代码将用户提供的数据进行 JSON 转换后直接当做 div 的属性 , 当用户构造了类似例子中的特殊字符串时 , 页面就会被注入恶意代码 , 所以要注意平时在开发中不要直接使用用户的输入作为属性 。
使用用户输入的值来渲染 a 标签的 href 属性 , 或类似 img 标签的 src 属性等const userWebsite = "JAVAscript:alert('xss');";<a href=https://www.isolves.com/it/aq/sj/2020-09-24/{userWebsite}>
如果没有对该 URL 进行过滤以防止通过 JavaScript: 或 data: 来执行 JavaScript , 则攻击者可以构造 XSS 攻击 , 此处会有潜在的安全问题 。用户提供的 URL 需要在前端或者服务端在入库之前进行验证并过滤 。
服务端如何防止 XSS 攻击服务端作为最后一道防线 , 也需要做一些措施以防止 XSS 攻击 , 一般涉及以下几方面:
- 在接收到用户输入时 , 需要对输入进行尽可能严格的过滤 , 过滤或移除特殊的 HTML 标签、JS 事件的关键字等 。
- 在输出时对数据进行转义 , 根据输出语境 (html/javascript/css/url) , 进行对应的转义
- 对关键 Cookie 设置 http-only 属性 , JS脚本就不能访问到 http-only 的 Cookie 了
- 利用 CSP (https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP) 来抵御或者削弱 XSS 攻击 , 一个 CSP 兼容的浏览器将会仅执行从白名单域获取到的脚本文件 , 忽略所有的其他脚本 (包括内联脚本和 HTML 的事件处理属性)
作者:陈吉
转发链接:https://mp.weixin.qq.com/s/HweEFh78WXLawyQr_Vsl5g
推荐阅读
- 正史中的关羽真有这么厉害吗 关羽是哪部作品的人物
- 三国干涉还辽中的三国指的是
- 三国中的贾诩是什么人物 贾诩是一个怎样的人
- 历史名著中的茶文化,茶文化之茶与神农历史记载
- 探究!一个数据包在网络中的心路历程
- 三十六计中的围魏救赵是什么意思 36计第二计围魏救赵的故事
- 大肠杆菌特效药在生活当中的作用是什么
- 儒家孝悌之道 儒学中的孝
- 曹操在官渡之战和赤壁之战中的不同结局给我们什么启示 官渡之战曹操胜,赤壁之战曹操败,启示
- 靈脂酒的功效与作用