访问控制除了通过授权进行控制之外,还有就是如何对输入参数进行控制呢?
我们经常听到某某业务因为存在安全漏洞被黑客利用,导致服务器权限被获取,或者数据泄露。这些漏洞包括:
- 缓冲区溢出。
- SQL注入。
- XSS(跨站脚本)。
- Path Traversal(路径遍历)。
- SSRF(服务侧请求伪造)。
- 上传脚本文件漏洞(WebShell)。
这些的漏洞被利用大多是因为输入参数的问题,这些参数变成了可执行的指令,或者跃出了信任的边界。那么我们该如何应对呢?
边界检查,防止缓冲区溢出
载荷本来只是数据的一部分,但通过精心构造里面的ShellCode(作为最终执行的代码)的内容和位置,溢出后ShellCode由数据变成了可执行的代码。
2003年8月爆发的冲击波病毒、2004年5月爆发的震荡波病毒,就是利用Windows中系统服务的缓冲区溢出漏洞进行攻击和传播,导致感染的电脑操作系统异常、不停重启。
应用系统除了自身需要安全编码之外,它所依赖的操作系统、运行环境、第三方开源组件也可能引入此类漏洞,这就要求我们关注操作系统及运行环境的补丁管理(补丁通常修复了已被发现的缓冲区溢出等漏洞)、开源组件的版本管理等.
不要拼接 SQL,防止 SQL 注入- 后端
如果是拼接 SQL,对应的SQL 如下所示,其中 id 是用户输入的内容
"select * from userinfo where id="+id;
假如用户输入的 id 为 1 and 1=1,后台没有做对应的参数校验,则将获取所有用户的信息。这就违背的数据的机密性。
比如我在浏览器上输入如下所示:
可以得到其他数据,则表示为 SQL 注入。
如何防护SQL 注入
-
推荐的写法是基于预编译(Prepare)和参数绑定(Bind)的参数化查询机制,否则就会出现“数据变指令”的情况,导致风险发生。
-
当不得不使用字符串类型的时候,可以将字符串中可能出现的单引号替换为两个单引号,缓解部分SQL注入。
-
不要将列名(即字段名)作为参数进行传递,一方面泄露了业务内部的逻辑信息,另一方面也可能引入SQL注入漏洞。如果需要用到相关的字段进行排序、聚合时,最好就是预先封装好相关的功能,或考虑使用索引(整型值)。
内容转义,防止跨站脚本(XSS)-前端
比如我在浏览器上输入了 JavaScript 脚本,如下所示:
如果可以得到如下结果:
则表示这个脚本执行了,应用就比较容易受到攻击。
如果这个脚本存储到数据库中,则是持久化 XSS 攻击,一般就是在博客评论区中,一旦黑客在评论区中植入一句话木马,所有访问这个评论区的用户就会受到对应的攻击.
如何防护 XSS
凡是用户提交的内容,只要返回到用户侧(包括用户本人及其他用户),就需要执行转义处理。重点关注语法闭合标签,如< > ' " ( )等,至少应包括这些字符的HTML转义(转义后的字符为< > '" ( ))。
采用CSP策略(Content Security Policy,内容安全政策)可缓解XSS风险,如在响应头部添加:
Content-Security-Policy: default-src 'self'
防止跨站请求伪造(CSRF)
CSRF由用户的浏览器自动发起,使用的是用户已认证通过的凭据,在Web应用上提交的请求或操作不是出自用户的本意。
比如黑客将文章中添加上对应的高危操作 URL 在 图片 img 标签上, 一旦用户浏览黑客发布的文章,则会自动去请求对应的URL, 在用户无感知的情况下访问。
这里的问题就是黑客提交的 img 标签
如何防护 CSRF
为表单添加一个隐藏的字段
如果表单中没有这个字段,或者字段值不匹配则表示不是合法的请求,不进行响应。
- 字段名称:通常会使用csrftoken、csrf、token、csrf-token等,
- 字段值:是临时生成的,仅使用一次,或在较短的时间窗内针对该用户重复使用,
- 只在用户浏览器和服务器之间共享,可以视为用户浏览器和服务器之间的约定,或共同的背景知识。
- 在实际提交时,CSRF Token不需要手工输入,浏览器会自动带上
配合验证码(CAPTCHA)使用
原理跟CSRF Token基本一致,但在用户体验上,多一个手工输入的过程。
再次身份认证
有的APP可以开启小额免密支付功能,虽然方便,但是也有可能为黑客开启了方便之门,因此,建议谨慎使用该功能,除非限额很小
防跨目录路径操纵
使用../../等形式进行路径遍历,读取敏感系统文件如/etc/passwd。
如何防护路径操纵
如业务无法避免,需要限定目录,并尽量使用整型的ID进行操作。
防 SSRF
SSRF(Server-Side Request Forgery,服务器端请求伪造),通常是由黑客提交经过构造的内网地址及参数,但由服务器侧发起的针对内网进行探测的请求,常用于攻击内部系统。
黑客通过发送内网的地址请求是否有对应的结果,如果有响应则可以知道服务器中有对应的内网存在,使用的框架等。
如何防护 SSRF
-
如业务无法避免地使用URL地址作为参数,最好使用白名单,即只允许访问指定的域名。
-
因为业务需要访问的地址可能是任意的。那么在这种情况下,至少需要将内部IP地址段纳入黑名单,禁止访问这些内部IP地址。