XSS
攻击原理,攻击者希望能让自己写到一段代码运行起来
最常见的有两种:
- 通过url传入
在地址栏中传入 ?name=小明 页面中打印name
如果传入的是 ?name=<script>alert('哈哈');</script> 页面就把alert('哈哈');运行起来了
- 通过数据库写入
网页应用会有一些用户表单,提交的内容重新从数据库读取出来打印到页面上
blog评论:<script>alert('哈哈');</script>
页面上运行了代码有什么危害
- 获取token,session,通常前端登录的token,session会储存在localStorage,sessionStorage,cookie中,通过JS代码获取之后再发一个ajax请求传给外部网站即可获得。
- 破坏页面,引入广告等
如何防范
- 使用现代前端框架 前端框架基本上已经做好了XSS的防护,将'<' '>'转义成< >,如果大家已经在使用现代前端框架,类似Vue,React,Angular,那么基本上打印层不会出什么问题。
- 后端过滤 对用户提交的表单数据过滤,将'<' '>'等特殊字符过滤
- 使用HttpOnly Cookie 如果你是使用cookie存储token,记得加上HttpOnly,这样可以防止前端JS读取
- JWT的密钥做长一些复杂一些 JWT作为一种标准化的Token,是可以通过穷举法来查secret的,长一些复杂一些可以加大破解难度,另外,也可以做非标准化的JWT,例如不表面加密算法,或改造加密算法
钓鱼嵌入
网站的登录页面如果被嵌入到iframe中会有风险,攻击者将网站的登录页面放到自己网站的iframe中,当你输入了正确的密码,攻击者可以用Javascript读取iframe里的内容获取密码。
利用你网站做广告,将你网站的有趣的内容嵌入到iframe中,在外部加入广告内容。
如何防范
- 不让其他网站嵌入,代码中加入
if(window.top !== window.self){ window.top.location = window.location;}
或
在响应header中加入 X-Frame-Options: deny
- 使用Https,使用https的网站嵌入到http网站不可用。
跨站提交数据
使用原始的 <from></form> 表单提交,浏览器是不验证跨域的,意味着你在a网站准备了一套一模一样的数据,提交到b网站是通过的。攻击者做出了吸引人的a网站,准备好了数据,引诱用户点击按钮(美女图片,广告关闭xx)等,提交数据到目标网站达到目的。
如何防范
- 短信验证码,为了确保请求是本人操作,因为没有其他的代码层面的防御方法所以银行系统发生转账等业务都需要验证码。
数据库注入
数据库注入指的是通过串改SQL语句来达到攻击目的。 最常见的数据库注入是通过user表获取账号密码,攻击者需要在网站上找到获取用户信息的查询,传入非法字符拼装出自己想要的结果。
例如有一个用户数据接口 api.example.com/user?id=1
后端程序员把获取到的id(值为1)拼装成了一个这样的SQL select name,email from user id = 1,黑客如果把id=1改写成id=1 and 1=0 union select * from user,这样最终的SQL就变了select name,email from user id = 1 and 1=0 union select password as name,email from user 这样就把用户的密码查了出来。
其实这些年随着前后端分离,后端框架的安全性提升,数据库注入已经不像过去这么容易成功。但是我们依旧是可以通过以下几个方法加强防御。
- 验证所有表单地址栏传入参数,例如上面的id=1,那么要验证这个传入的id是否是数字。
- 禁用Mysql等数据库的union语句。
- 设计数据库的时候不要使用user作为表名,或者不用password作为密码的名字,让黑客无法猜测出查询内容。
- 使用数据库框架处理请求而非自己瓶装sql语句,例如Java有JPA,NodeJS有TypeORM
邮件服务
邮件服务虽然在国内不常用(我们都是用微信登录,手机号登录),但确是国外常见使用的方式和黑客常常攻击目标。
通常开发一个发送邮件的功能我们会找一个第三方的代发,代发的目的1是降低自己服务器的发送成本,2是代发服务器发出的邮件不容易进到“垃圾邮件”分类。
那么黑客攻击的目标是什么?他们会找那些可编辑的邮件内容功能,例如你的网站有一个分享功能,写一段祝福文字,分享到好友的邮箱里。因为文字是自定义的,黑客就会利用这个功能,大量的制造钓鱼邮件,发送到大量的邮箱里。因为你使用了第三方的服务,这些邮件还可以准确的投到别人非垃圾分类里。
如何防范?
- 对邮件做邮件模板,限制里面的文字
- 对邮件内容加以过滤,不允许里面加入任何html代码,或者类似< a >标签的链接
短信验证码
短信的问题类似邮件,如果有给了别人自定义文字的机会,就会允许黑客乱发内容。不过国内的短信平台都对短信内容加上了模板限制,所以基本是安全的。
文件上传
这已经是早期安全问题了,在过去还没有阿里云AWS的时候,通常我们都是购买一个个虚拟主机,在上面跑个php之类的脚步程序。那时候存储,数据库,运算3合一一体在同一台服务器上。开发一个类似论坛这样的系统,会有文件文件附件上传的功能,上传好的文件又会被存在同一个服务器上。只要传上一个php木马文件,找到文件地址,用浏览器就可以直接打开运行。
当今服务器的架构文件上传都会存在oss,s3上,这类问题几乎不存在了。
图片盗用
这里指的是你自己网站的图片,被别的网站盗链。很多云厂商都推出了防盗链的方法,一般的说原理就是判断访问过来的请求是否符合某个域名要求,如果符合则可以获取资源,如果不符合则无效。
其他
密钥
一般是调用第三方服务使用的APPSecret不应该打包到前端中,也不应该提交到Github之类的版本库中,秘钥传递可以通过私聊或者其他加密传说软件例如keybase来传,而不是QQ或者微信。
Token
登录成功返回的Token如果是记录在cookie里要记得加上httponly,防止JS读取。服务器生成的Token不要做成无限期的,必须要有过期时间。对于JWT Token产生过程中需要的Secret,应该要足够复杂,否者是可以通过穷举法进行破解的。
用户密码
限制用户输入的密码要求设置足够复杂,在服务器中也需要用足够复杂的加密方式加密后存储。
验证码
对于公开登录功能或者付费等功能,都必须加上验证码,验证码可以是自己开发,也可以通过第三方服务获取。