前言
昨天我们团队的安全大佬给我们开展了一个安全培训,怕自己之后很容易会忘掉。所以写篇文章来记录一些常见的安全问题以及应对策略。同时也方便自己随时阅读,加深对于信息安全的理解
常见的安全问题
sql Injection(sql注入)
sql注入的核心原理是因为没有对用户输入的内容做验证和净化处理。攻击者在输入的内容里构造恶意sql语句然后提交给服务端执行(好难举例,我在我自己的项目里没构造出来)
减轻或者弱化sql注入的方式:
- 对用户提交的数据进行内容转义/内容验证
- 白名单机制
- 使用预编译语句,参数化查询的方式(这里我之前写博客后端服务的时候,有看别人这么写但不是很清楚其中缘由。这次有点恍然大明白的感jio)
- 从策略上来说,最直接有效的方式就是充钱买支持防御注入攻击的WAF(应用程序防火墙),你懂的,充钱能使你更强
其中呢,前端能做的就是对输入的数据做一些校验(其实也没啥太大用处,因为用户的输入是随心所欲的,总会有漏洞可以绕过验证)。根源上的解决方法还得是预编译语句和参数化的查询,它的大体过程是sql服务器先执行sql存到缓存池里,然后把输入的数据当作参数变量传进来。而sql服务器不会把参数变量里的值当成sql语句的一部分,从而防止注入。
Broken Authentication(中断身份认证)
常见问题:
- 弱口令
- 口令长度是否大于8
- 口令是否包含特殊字符,大写字母,小写字母,数字的三类
- 密码泄露
- 密码爆破
- 明文密码
解释一下Session覆盖。session或cookie的覆盖(它被用作修改指定用户的密码,可能就是用户名),而服务器端只是简单判断了一下修改链接的key是否存在就可以修改密码了,而没有判断key是否对应指定用户名。举个例子:先向自己邮箱A发一封找回密码,再向用户B的邮箱发一封,当前浏览器记录用户B的账户信息,然后去自己的邮箱A点击找回密码链接,读取了存在浏览器用户B的账户信息,成功修改了密码
主要对策:
- 使用安全的认证框架
- 正确加密
- 禁用弱口令
Sensitive Data Exposure (敏感信息泄露)
这个问题常见于http传输中,因为http协议是一个明文传输的协议。
敏感信息定义
- 业务流程的敏感信息(肯定不止这些,这里只列出一些比较常见的信息)
- token
- session
- cookie
- password
- 用户/客户标识信息
- 电话号码
- 身份证号码
- 职位
- 客户的资产信息(潜在客户,合同信息等)
- 生物特征信息(指纹,虹膜等)
保护敏感信息的对策
敏感信息的保护通常需要贯穿整个业务流程
- 在infra层要采用符合标准的TLS版本,(大于等于1.2),并且有选择的禁用密码套件
- 采购可信CA的证书,并且定期更新
- 对服务器里的用户信息进行脱敏
- 使用安全的对称/非对称加密算法
- 采用POST方法提交敏感数据
XML External Entities (XXE)(XML 外部处理器漏洞)
XXE通常会出现在基于SOAP的系统中,通常需要启用DTD(document type definitions)。
在应用里比较有可能存在的XXE的点是,如果某些功能是通过SAML来完成的,SAML使用XML作为identity assertion
另外经过测试,xx应用的Excel文件上传下载部分,不受XXE的影响(XML解析器安全)。
另外如果需要整体上快速排查XXE漏洞,可以使用源代码分析工具:https://owasp.org/www-community/Source_Code_Analysis_Tools
Broken Access Control(中断访问控制)
原因
限制认证的用户可以实现哪些操作的命令没有得到正确的执行。
问题
攻击者可以利用这些漏洞访问未经授权的功能和数据,例如访问其他用户的账户,查看敏感文件,篡改其他用户的数据,更改访问权限等。
对策
- 最小权限原则:只给当前程序运行需要的最小信息或资源。可以有效降低被恶意用户利用时造成的损失
- 基于角色的访问控制(对角色权限):对系统操作的各种权限不是直接授予具体的用户,而是在用户集合与权限集合之间建立一个角色集合。每一种角色对应一组相应的权限。一旦用户被分配了适当的角色后,该用户就拥有此角色的所有操作权限。这样做的好处是,不必在每次创建用户时都进行分配权限的操作,只要分配用户相应的角色即可,而且角色的权限变更比用户的权限变更要少得多,这样将简化用户的权限管理,减少系统的开销。
- 日志记录访问:对用户的操作进行日志记录,出现异常时可以及时排查原因,可以有效降低损失
security misconfiguration(错误安全配置)
原因
- 安全运营
- 比如未修复的漏洞
- 访问默认账户
- 不再使用的页面
- 未受保护的文件和目录等
对策
程序中接入的第三方提供的东西都需要进行安全配置外,还必须要及时进行更新和升级。
XSS(跨站脚本攻击)
原因
网站将用户输入的内容输出到页面上,在这个过程中可能有恶意代码被浏览器执行
跨站脚本攻击,它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
需要注意的是XSS是一个完全于客户端触发的安全风险,涉及到服务器端的部分在现实意义的攻击里通常是XSS+CSRF获得用户的Token/Cookie/其他Credentials
对策
- 验证所有输入数据,前端对用户提交内容进行内容验证/内容转义
- 对输出数据进行适当编码,防止成功注入的恶意脚本被运行
具体参见下面
- 输入验证:某个数据被接受为可被显示或存储之前,使用标准输入验证机制,验证所有输入数据的长度、类型、语法以及业务规则。
- 输出编码:数据输出前,确保用户提交的数据已被正确进行entity编码,建议对所有字符进行编码而不仅局限于某个子集。
- 明确指定输出的编码方式:不要允许攻击者为你的用户选择编码方式(如ISO 8859-1或 UTF 8)。
- 注意黑名单验证方式的局限性:仅仅查找或替换一些字符(如"<" ">"或类似"script"的关键字),很容易被XSS变种攻击绕过验证机制。
- 警惕规范化错误:验证输入之前,必须进行解码及规范化以符合应用程序当前的内部表示方法。请确定应用程序对同一输入不做两次解码。对客户端提交的数据进行过滤,一般建议过滤掉双引号(”)、尖括号(<、>)等特殊字符,或者对客户端提交的数据中包含的特殊字符进行实体转换,比如将双引号(”)转换成其实体形式",<对应的实体形式是<,<对应的实体形式是>以下为需过滤的常见字符:
1 | [1] |(竖线符号) |
Insecure Deserialization(不安全的反序列化)
不安全的反序列化最严重的会带来带来RCE(远程代码执行),通常会被用于进行重放攻击,注入攻击和权限提升。
序列化
最严格的禁止反序列化的方式是不接受非受信来源的序列化对象,序列化反序列化问题的根源是语言特性,即面向对象语言所具有的反射机制(动态获得所属类的对象来调用对应的方法)
对策
- 缓和方式是在序列化和反序列化的时候进行完整性校验(通常为Hash校验或者签名),也可以进一步进行加密,进行严格类型控制;如果可能,对于不同权限的对象进行隔离,为序列化和反序列化操作提供日志记录,监控inbound/outbound流量,对于持续进行反序列化的操作提供预警。
- 关注了解使用了的哪些组件进行了序列化和反序列化操作,他们的实现方式和安全措施是什么,是否启用,是否存在已知的漏洞,定期关注版本发布和升级。
Using Components with Known Vulnerabilities(使用含有已知漏洞的组件)
一方面是在选用组件的时候选用名声可信,社区活跃,安全机制较为完善的第三方组件;另一方面需要持续关注新漏洞的发布。
Insufficient Logging & Monitoring. (不足的日志和监控)
这部分属于安全运营部分,主要是在程序设计时候要留有足够的日志整段信息来追踪漏洞,
Cross-site Request Forgery(跨站请求伪造)
这个是培训时没有说明但实际上对FE来说是需要了解的。所以在这里加进来进行补充说明。
原理
- 用户C登录受信任的站点A
- 浏览器生成站点A的cookie信息
- 未登出的情况下访问恶意网站B(其实登出也不一定,因为不能保证cookie登出后就会失效)
- 网站B向网站A发起请求,该请求会带上步骤2的cookie信息
- 网站B通过该cookie信息,伪装成用户C进行操作(邮件/信息/转账等等)
对策
- 验证 HTTP Referer 字段:Referer字段是用来记录请求的来源地址,因为CSRF一般需要自己构造表单来请求。所以referer字段会不一样,所以对于referer不符合的,直接拒绝请求
- cookie中加入hash: 在cookie中加入hash,然后在后端校验hash值是否正确,来判断请求是否是真的客户发送的
- cookie设置为httpOnly:可以有效减少cookie被获取的风险
- 其实总的来说,上面的方法其实防御思路都一样。就是通过在请求中加入攻击者伪造不了的信息,然后通过这些信息来判断请求是否是真正的客户发送的。当然这些信息不应该存在cookie中
信息安全设计思路:
- 系统设计要有适度安全冗余,冗余是指关键功能的安全保障要多层。
- 流行的攻击方式要从设计上就预留应对空间。比如SQL Injection要保证使用的数据库支持参数化查询,比如应对不安全的反序列化,要预留设计数字签名校验机制的空间。
- 最小化权限原则
- 验证用户输入(天然认为用户的输入不安全的设计思路)
- 失败默认原则,白名单优先于黑名单
- 默认安全,就是默认配置即认为可提供可靠安全。
- 权限分离原则,进一步,矩阵访问控制设计。
- 服务器端的校验比客户端优先
总结
作为前端,我们也需要了解信息安全的重要性。并且在coding的时候也需要注意程序安全上是否有存在隐患。😘