查漏补缺-前端安全之XSS与CSRF
XSS
XSS(Cross
Site
Scripting
)跨站脚本攻击
简称本应为
css
,但是为了防止与CSS(Cascading Style Sheets,层叠样式表)搞混,就取为xss
跨站脚本攻击就是用 JS 脚本攻击,案例如下:
情景模拟
假设有一个前后端不分离的网站,后端用express
搭建,文件 app.js
内容如下
1 |
|
而其返回的 HTML
页面 index.html
内容如下:
1 |
|
现在在浏览器中输入URL:http://localhost:3000/?xss=123 ,title已经被默认赋值为 express
,xss
则被赋值为 123,可以得到如下页面
如果这时,我们把参数换成一个script
标签,并且在script
里面写个alert
,用来模拟脚本攻击,具体URL为:
1 |
|
URL里可以设置任何类型的参数,所以理论上可以写一个输入框,这样用户可能在访问网址时弹出输入框,并误以为这是银行网站自己弹出的内容,从而在输入框中输入如密码等重要信息,而黑客已经在后台获取了这些资料
XSS的危害
- 窃取
cookie
信息:黑客可以在其他电脑上模拟登录状态 - 可以监听用户行为:可以监听用户点击键盘的行为,得到用户信息
- 伪造登录窗口
- 在你的页面生成浮窗广告
浮窗广告例子:在body中添加一个 div
1 |
|
如何注入?
那么问题来了,XSS是在URL中写入参数,用户又不会自己入侵自己,如何将脚本放到别人的客户端上运行呢?
- 反射型攻击:在
url
中写入参数,也就是上面的例子,比如攻击者发送的钓鱼短信等等,如果受害者点击并且执行,就会执行恶意脚本
- 存储型攻击:这种情况更加复杂一些,比如某网站存在一个评论区,我在评论区输入脚本,那么连带脚本的这部分内容就会被存入到数据库中,其他受害者点击这些评论时(可能模拟为某些按钮或文本),就有可能触发这类内容
DOM型攻击:一种基于 HTML 解析 DOM 过程中的安全漏洞进行的跨站攻击,攻击的过程与反射型XSS攻击极其类似,差异在于反射型XSS会把攻击脚本传递给服务器,而DOM型XSS不需要,从而可以绕过WAF、躲避服务端的检测。
DOM型XSS攻击通常也是攻击者诱导用户访问一个恶意网站,用户在输入数据后,js脚本将这些内容组合成被篡改的DOM片段,并在其中注入恶意脚本,而浏览器只要解析这些DOM片段,就会执行这些恶意脚本,从而窃取用户信息。
如何防范XSS
- 对输入参数进行强校验,把不安全字符(如 <, >, / 等) 过滤,从而避免浏览器执行这些内容
- 将用户输入的内容返回到页面上时,同样进行校验,防止被解析为HTML标签
- 使用
HTTPOnly
cookie,这样 js 脚本不能读取到 cookie 信息 - 使用如验证码等安全控件来应对一些特殊页面(登录、支付页面)
- 设置
CSP
(Content Security Policy
),通过白名单和黑名单限制加载的资源类型和来源,从而防止恶意脚本的加载和执行 - 使用
innerText
或textContent
等更安全的 API 取代innerHTML
- 限制用户输入
- 提示用户小心恶意链接
CSRF
CSRF
(Cross
Site
Request
Forgery
) 跨站请求伪造
是指指恶意攻击者利用用户已经登录其他网站的“身份”来伪造用户的请求
受害者正常访问 aa.com ,其登录状态保存在浏览器中
而如果其访问 bb.com(恶意网站),网站会利用同一个浏览器中 aa.com 的登录状态,直接向 aa.com 发送其他恶意请求
如何防范
- 利用好
Cookie
的SameSite
属性,防止跨站点使用cookie
- 服务端验证请求来源,比如
Origin
字段记录了请求来源地址,杜绝第三方站点请求源 - 在用户进行敏感操作前进行用户身份验证
- 使用
CSRF Token
,在提交请求时一并提交,由服务端进行验证 - 设置
CSP
(Content Security Policy
),通过白名单和黑名单限制加载的资源类型和来源,从而防止恶意脚本的加载和执行