这是我参与「第四届青训营 」笔记创作活动的第5天
一、XSS
- 永远不相信用户的提交内容
- 不要将用户提交内容直接转化为DOM
现成工具
前端:
- 主流框架默认防御 XSS
- goole-closure-library
服务端(NODE)
- DOMPurify
二、CSP
- 哪些源(域名)被认为是安全的
- 来自安全源的脚本可以执行,否则直接报错
- 对eval+inline scripe 说不
服务器的响应头部
浏览器meta
\
三、CSRF的防御
1、判断请求头中的 Referer
这个字段记录的是请求的来源。
比如 www.example.com 上调用了百度的接口
api.map.baidu.com/service ,那么在百度的服务端,就可以通过 Referer 判断这个请求是来自哪里。
在实际应用中,这些跟业务逻辑无关的操作往往会放在拦截器中(或者说过滤器,不同技术使用的名词可能不同)。意思是说,在进入到业务逻辑之前,就应该要根据 Referer 的值来决定这个请求能不能处理。
在 Java Servlet 中可以用 Filter(古老的技术);用 Spring 的话可以建拦截器;在 Express 中是叫中间件,通过 request.get(‘referer’) 来取得这个值。每种技术它走的流程其实都一样。
但要注意的是,Referer 是浏览器设置的,在浏览器兼容性大不相同的时代中,如果存在某种浏览器允许用户修改这个值,那么 CSRF 漏洞依然存在。
2、在请求参数中加入 csrf token
讨论 GET 和 POST 两种请求,对于 GET,其实也没什么需要防范的。为什么?因为 GET 在“约定”当中,被认为是查询操作,查询的意思就是,你查一次,查两次,无数次,结果都不会改变(用户得到的数据可能会变),这不会对数据库造成任何影响,所以不需要加其他额外的参数。
所以这里要提醒各位的是,尽量遵从这些约定,不要在 GET 请求中出现 /delete, /update, /edit 这种单词。把“写”操作放到 POST 中。
对于 POST,服务端在创建表单的时候可以加一个隐藏字段,也是通过某种加密算法得到的。在处理请求时,验证这个字段是否合法,如果合法就继续处理,否则就认为是恶意操作。
这个 html 片段由服务端生成,比如 JSP,PHP 等,对于 Node.js 的话可以是 Jade 。
这的确是一个很好的防范措施,再增加一些处理的话,还能防止表单重复提交。
可是对于一些新兴网站,很多都采用了“单页”的设计,或者退一步,无论是不是单页,它的 HTML 可能是由 JavaScript 拼接而成,并且表单也都是异步提交。所以这个办法有它的应用场景,也有局限性。
3、新增 HTTP Header
思想是,将 token 放在请求头中,服务端可以像获取 Referer 一样获取这个请求头,不同的是,这个 token 是由服务端生成的,所以攻击者他没办法猜。