研发安全
研发安全说明
本章,我们主要从前端、后端和服务器这三个方面对研发过程中涉及到的安全问题进行简单的介绍!
文章目录
1、🛡️ 前端
1.1、数据加密 🥇🥇🥇
前端用户在登录系统或提交表单时,应该对其中的 关键数据进行加密(如:登录账号、密码、手机号、身份证……),避免这些关键数据直接暴露在外。
加密方式
我们可以使用 AES 或 RSA 等常用的加解密方式,以便传递给后端进行加解密使用。
另外需要我们注意的是,前端应妥善保管加解密所需要的公钥或私钥,条件允许的情况下,是否考虑定期更换公钥或私钥。
加密传输
下图所示既是用户登录接口通过AES对登录账号和密码加密后传输的效果:

1.2、密码复杂度 🥇🥇🥇
在我们的管理系统中,涉及到创建登录账号的时候,都会设置一个密码,然而这个密码的复杂度往往会被忽略。
弱密码
如123456、123、000、111111、666666、888888、123456789……等这些都是常见的弱密码,我们应该尽量避免使用这类的弱密码。
因此,为了账号密码的安全性,强烈建议使用一定复杂度的密码,如:必须包含大小写字母、数字、特殊字符,长度为 8 至 16 位
密码复杂度验证
下图所示为密码复杂度验证:

1.3、记住密码 🥇🥇🥇
通常在我们的系统中,登录界面有可能会有记住密码的功能。
如果有该功能,那么一定要将密码设置为密文形式(加密后的结果)!!!
记住密码时设置为明文
如果记住的密码没有进行加密处理,那么我们可以在浏览器中按F12审查密码输入框将type属性删除就可以看见密码内容了,如下图所示:

记住密码时设置为密文
因此,在记住密码的时候,应该将密码进行加密处理,这样密码就不会直接暴露在输入框内了,如下图所示:

1.4、SQL 注入攻击 🥇🥇🥇
SQL注入指 Web 应用程序 对用户输入数据的合法性没有判断或过滤不严,攻击者可以在 Web 应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。防范措施
分级管理
对用户进行分级管理,严格控制用户的权限,对于普通用户,禁止给予数据库建立、删除、修改等相关权限,只有系统管理员才具有增、删、改、查的权限。
参数传值
程序员在书写 SQL 语言时,禁止将变量直接写入到SQL语句,必须通过设置相应的参数来传递相关的变量,从而抑制 SQL 注入。数据输入不能直接嵌入到查询语句中,同时要过滤输入的内容,过滤掉不安全的输入数据(如
' '单引号、" "双引号、:冒号等字符),或者采用参数传值的方式传递输入变量。这样可以最大程度防范 SQL 注入攻击。漏洞扫描
系统管理员可以通过采购一些专门系统的SQL漏洞扫描工具,通过专业的扫描工具,可以及时的扫描到系统存在的相应漏洞。漏洞扫描工具只能扫描到SQL 注入漏洞,不能防范SQL 注入攻击。
多层验证
增加黑名单或者白名单验证。黑名单指:若用户在输入中,包含明显的恶意内容则拒绝该用户的请求;而白名单指:检查用户输入是否符合预期的类型、长度、数值范围或其它格式标准。在使用白名单验证时,一般会配合黑名单验证。
数据库信息加密
具体参见:传统的加解密的方法大致可以分为三种[1]
1.5、文件上传漏洞 🥇🥇🥇
文件上传漏洞指文件上传功能代码没有限制用户上传的文件后缀及类型,就让攻击者可以上传任意后台文件,然后将这些文件传入解释器中,就可以在远程服务器上执行恶意代码脚本。防范措施
限制用户提交文件的后缀及类型;
定义文件上传白名单,只能上传指定类型及后缀的文件;
文件上传目录禁止执行脚本解析,避免攻击者二次攻击。
1.6、URL 越权访问 🥇🥇🥇
系统已经对 URL 的访问做了限制,但这种限制却实际并没有生效。攻击者能够很容易的就伪造,请求直接访问未被授权的页面。
防范措施
在公共模块增加校验方式,查看是否具有对应权限;
监听路由跳转,在路由跳转之前,增加校验;
和后台联调,将对应的信息存入 Cookie,在数据访问时进行对比。
1.7、XSS(跨站脚本攻击)
XSS指攻击者通过在网页输入添加恶意 Html 代码,用户在访问页面的时候,嵌入在网页的代码就会被执行,可对用户进行盗取 Cookie 信息、会话劫持等各种攻击。
危害
盗取各类用户账户;
控制数据,对敏感信息进行增删改查;
盗窃企业机密数据;
非法转账;
强制发送电子邮件;
网站挂马。
防范措施
输入过滤,对输入的数据进行严格校验,诸如<script/>、<img/>、<a/>等标签进行过滤。但是此方法只是在 Web 端进行了初步过滤,攻击者可能通过工具绕过前端的输入限制,因此还需后台服务器在接收到数据后,对特殊危险字符进行过滤或者转义,再存储到数据库;
编码,一些常见的符号,如<>在输入的时候要对其进行转换编码,这样做浏览器是不会对该标签进行解释执行的,同时也不影响显示效果;
限制,通过以上的案例我们不难发现 XSS 攻击要能达成往往需要较长的字符串,因此对于一些可以预期的输入可以通过限制长度强制截断来进行防御;
HttpOnly Cookie,预防 XSS 攻击窃取用户 Cookie 最有效的防御手段。在设置 Cookie 时,加上HttpOnly参数,就可以避免该网页被 XSS 攻击时,Cookie 信息被盗取(可兼容至 IE6),但缺点是作用有限,只能保证 Cookie 的安全;
CSP,原理其实就是白名单机制,开发者明确告诉客户端(浏览器)哪些资源可以加载并执行,我们只需要提供配置,其他的工作由客户端(浏览器)来完成。通过<meta>标签开启
<meta http-equiv=“Content-Security-Policy” content=“配置项” >具体配置项
default-src:用来设置每个选项的默认值
script-src:外部脚本
style-src:样式表
img-src:图像
media-src:媒体文件(音频和视频)
font-src:字体文件
object-src:插件(比如 Flash)
child-src:框架
frame-ancestors:嵌入的外部资源(比如<frame>、<iframe>、<embed>和<applet>)
connect-src:HTTP 连接(通过 XHR、WebSockets、EventSource 等)
worker-src:worker 脚本
manifest-src:manifest 文件
block-all-mixed-content:HTTPS 网页不得加载 HTTP 资源(浏览器已经默认开启)
upgrade-insecure-requests:自动将网页上所有加载外部资源的 HTTP 链接换成 HTTPS 协议
plugin-types:限制可以使用的插件格式
sandbox:浏览器行为的限制,比如不能有弹出窗口等。
report-uri:有时,我们不仅希望浏览器帮我们防止 XSS 的攻击,还希望将该行为上报到给定的网址,该选项用来配置上报的地址例子
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
script-src(脚本):只信任当前域名
object-src(标签):不信任任何 URL,即不加载任何资源
style-src(样式表):只信任 cdn.example.org 和 third-party.org
child-src(框架【frame】):必须使用 HTTPS 协议加载
其他资源:没有限制
1.8、CSRF(跨站请求伪造)
CSRF攻击(Cross-site request forgery)是一种挟制用户在当前已登录的 Web 应用程序上执行非本意操作的攻击方法。与 XSS 相比,XSS利用的是用户对指定网站的信任,而CSRF利用的是网站对用户网页浏览器的信任。例子
假如一家银行用以运行转账操作的 URL 地址如下:http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName
那么,一个恶意攻击者可以在另一个网站上放置如下代码: <img src="http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">
如果有账户名为 Alice 的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失 1000 资金。
这种恶意的网址可以有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛、博客等任何用户生成内容的网站中。这意味着如果服务端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。
通过这个例子能够看出,攻击者并不能通过CSRF 攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是欺骗用户浏览器,让其以用户的名义运行操作。
1.9、OS 命令注入攻击
OS命令注入(OS Command Injection)类似于上述的 SQL 注入,区别于应用场景不同。OS 注入攻击是指程序提供了直接执行 Shell 命令的函数的场景,比如在构造 OS 命令时使用了外部输入的数据,如果没有对外部输入中可能影响 OS 命令的特殊元素进行过滤,或是过滤不充分,就有受到 OS 命令注入攻击的风险。OS 命令注入漏洞的形成需要同时满足以下三个条件
使用了内部调用 Shell 的函数(
system、open等);将倍加传入的参数传递给内部调用的 Shell 的函数;
参数中 Shell 的元字符(如
*、?、[]、\等)没有被转义。
防范措施
- 白名单校验
对用户
输入的参数进行过滤校验。当然黑名单也不是不可以,只是需要考虑的情况比较多,相比之下还是白名单简单高效。当然,如果可以的话,最好不要允许用户输入参数。 - 使用execFile/spawn
在 Node.js 中除了
exec()之外,还有execFile()和spawn()两个方法也可以用来执行系统命令。它们和exec()的区别是后者是直接将一个命令字符串传给/bin/sh执行,而前者是提供了一个数组作为参数容器,最后参数会被直接传到 C 的命令执行方法execve()中,不容易执行额外的参数。不过这个方法也不是绝对安全,因为这个只是利用了执行的命令只接收普通参数来做的过滤,但某些命令(如
/bin/find)提供了-exec参数,后续的参数传入后会被其当成命令执行。
1.10、点击劫持
点击劫持(Click Jacking),也被称为 UI-覆盖攻击,顾名思义,和点击事件有关,利用用户的点击操作,来完成非用户本意的操作。这种攻击利用了 HTML 中<iframe>标签的透明属性。虽然你点击的是你正在访问的页面,但其实上面覆盖了一层恶意攻击者精心构建的一个透明页面。
防范措施
- JavaScript中禁止内嵌普通页面的
top对象为window,而iframe的 top 对象不等于 window 对象,所以可以在 JS 代码中插入:if (top.location != window.location) { top.location == window.location; }这样如果存在嵌套的
iframe,页面就会跳转,避免遭到点击劫持。但是如果攻击者设置iframe的属性sandbox="allow-forms"时,这种方法就会失效。 - X-FRAME-OPTIONS 防止内嵌
服务器端可设置 HTTP 头
"X-Frame-Options:DENY"来让浏览器主动禁止iframe内嵌。不过这种方式在 HTTP 中不可靠,恶意攻击者可以窃听篡改 HTTP 请求来修改 HTTP 头。 - NoScript 扩展
对于Firefox的用户,使用 NoScript 扩展能够在一定程度上检测和阻止点击劫持攻击。利用 NoScript 中
ClearClick组件能够检测和警告潜在的点击劫持攻击,自动检测页面中可能不安全的页面。 - 其他辅助手段
例如上述
XSS和CSRF攻击的防御方法。
1.11、HTTP 请求劫持
HTTP劫持是在使用者与其目的网络服务所建立的专用数据通道中,监视特定数据信息,提示当满足设定的条件时,就会在正常的数据流中插入精心设计的网络数据报文,目的是让用户端程序解释错误的数据,并以弹出新窗口的形式在使用者界面展示宣传性广告或者直接显示某网站的内容。防范措施
- 全网站https
很大一部分 HTTP 劫持,主要的原因就是在传输数据时都是明文的,使用了
HTTPS后,会在 HTTP 协议之上加上TLS进行保护,使得传输的数据进行加密,但是使用 HTTPS,一定要注意规范,必须要全站使用 HTTPS,否则只要有一个地方没有使用 HTTPS,明文传输就很有可能会被 HTTP 劫持了。例如,使用https://www.baidu.com来访问百度。但是此方法可能会降低性能(因为多了
TLS握手所带来的 2 次RTT延时),此外,由于运营商可能会使用DNS劫持,在 DNS 劫持之下,HTTPS 的服务完全用不了了,所以会导致白屏。 - 加密代理
在
用户和目标Web服务器之间增加一个代理服务器,用户和代理之间会经过运营商的节点,这里使用各种加密手段保证安全,在代理服务器与 Web 服务之间使用 HTTP 请求,只需确认代理与 Web 服务之间不会被 HTTP 劫持就可以避开 HTTP 劫持。
1.12、DDOS 攻击
DDOS(Distributed Denial of Service)即分布式拒绝服务攻击,是指处于不同位置的多个攻击者同时向一个或数个目标发动攻击,或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。防范措施
- 安装入侵检测工具
安装入侵检测工具(如
NIPC、NGREP),经常扫描检查系统,解决系统的漏洞,对系统文件和应用程序进行加密,并定期检查这些文件的变化。 - 大数据智能分析
对海量数据进行分析,进而对合法用户进行模型化,并利用这些指纹特征,如:
Http 模型特征、数据来源、请求源等,有效地对请求源进行白名单过滤,从而实现对 DDoS 流量的精确清洗。 - 防火墙
在系统中加装
防火墙系统,利用防火墙系统对所有出入的数据包进行过滤,检查边界安全规则,确保输出的包受到正确限制。
2、🔰 后端
2.1、输入验证 🥇🥇🥇
防止输入注入型攻击,所有的输入数据都要检查,除了前端检查外,为防止使用工具、程序绕开前端检查直接把数据发送给服务器,后端也要检查所有输入数据。
未能正确验证输入可能会导致安全漏洞,例如SQL 注入或跨站点脚本(XSS)攻击,攻击者可以利用这些漏洞执行恶意代码、访问未经授权的数据或破坏整个应用程序。因此,应始终在服务器端验证和清理用户输入,以确保它符合预期的标准并且没有恶意内容。
验证
依据产品文档的要求进行合法性检查,数值型,手机号,时间,邮箱等;
检查文本型是否含控制字符,过滤掉控制字符;
检查文本型的长度;
Querystring 中参数值字符串转义,使用 UrlEncode 函数处理。
2.2、认证授权 🥇🥇🥇
用户身份认证和授权是保护后端系统安全的重要措施,开发者应该使用强密码和加密技术来保护用户凭证,同时还应该限制用户对受保护资源的访问权限。
未能实施适当的身份验证和授权机制可能会使应用程序容易受到未经授权的访问和数据泄露。
我们可利用JWT(JSON Web Token)或OAuth等行业标准协议来确保安全的用户身份验证并实施适当的授权控制。
常见的应用场景就是我们对外提供的接口中,在 Header 中增加用户 Token 的授权验证。
2.3、越权类漏洞 🥇🥇🥇
越权访问类(Broken Access Control)漏洞是一种非常常见的逻辑安全漏洞,可以理解为服务端对客户端的数据操作请求过分信任,一个用户一般只能对自身的信息进行增删改查,然而由于后端开发人员的疏忽,没有对用户的增删改查权限进行严格校验或根本就没有校验,从而导致被攻击账户拥有了对其他账户的增删改查权限。越权类访问类漏可以划分为水平越权访问、垂直越权访问、无权限控制三大类。
1、水平越权访问
水平越权访问是由于服务器端在处理用户的增删改查请求时没有判断数据的所属人或者所属主体而导致的越权数据访问漏洞。举个例子:
假如有 A 和 B 两个账户,正常情况下 A 账户是不能查询到 B 账户的数据的,但是 A 账户使用一些方式例如传入 B 的 ID,而服务器端没有校验此 ID 的数据属于 A 而导致了 A 可以查到 B 的数据,这样就产生了水平越权访问的漏洞。
2、垂直越权访问
垂直越权访问又叫做权限提升攻击,攻击方法是使用低权限的账户发送高权限账户的请求,从而获得高权限的操作。很多系统在做权限访问控制时只做了展示层面的控制(也就是我们通常所说的角色模块权限),没有做后端接口层面的权限校验,这就导致一个低权限账号可以通过猜测 Url 的方式获取到本不具有的功能。
3、无权限控制
无权限控制顾名思义就是做系统的时候考虑不到做权限控制或者做了权限控制但是做得漏洞百出。常见的越权类漏洞
在分配权限时,违反了 “最小权限原则” 或没有 遵从“默认拒绝”的策略 --即应该给特定用户分配特定的角色和权限,因为没有这么做而导致用户有了本不该具备的权限;
通过修改 URL(参数篡改或强制浏览)、内部应用程序状态或 HTML 页面,或使用攻击工具修改 API 请求来绕过访问控制校验;
特权提升,未登录即成为用户或以用户身份登录后即成为管理员;
提供通过明文的唯一标识符的方式查看或编辑账户信息;
没有配置跨域或者配置错跨域从而导致允许来自未授权或不可信的来源可以访问 API;
允许未经授权的用户访问需要授权后才能访问的功能。
2.4、加密机制失效类漏洞(Cryptographic Failures)
如何理解加密机制失效类漏洞?
据 OWASP 的统计数据,加密机制失效类(Cryptographic Failures)漏洞数量已经上升到第二位。加密机制失效类漏洞之前被称为敏感数据泄类漏洞,但是敏感数据泄只是结果而不是根本原因。应该这么说,由于加密机制失效或者缺少加密机制而导致敏感数据泄露。
加密机制失效是一个统称,有很多情况都可以称为加密机制失效,以下罗列了比较常见的一些:
应该被加密的数据没有进行加密;
在代码中硬编码了密钥或密码;
使用了已经可以被破解或已经被证明有漏洞的加密算法;
使用了比较弱的密钥,可以很容易被猜到;
服务器配置不当或者应用程序 bug 导致的数据泄露。
常见的加密机制失效类漏洞
数据使用前首先要确定是不是敏感数据(包括静态数据、需要存储的数据、要进行网络传输的数据等)。
例如密码、银行卡号码、身份证号码和商业秘密等显而易见的敏感数据;
各种数据保护法或隐私保护法规定的敏感数据,例如欧盟的通用数据保护条例(GDPR),PCI 数据安全标准(PCI DSS)等。
需要从以下这些方面检查是否存在加密机制失效漏洞:
数据传输过程中是否是以明文的方式传输的?
程序中是否使用了已经被废弃的加密算法或者不安全的加密算法?是否使用了加密算法的不安全的模式?例如 ECB 模式。
秘钥强度是否足够?同一个秘钥是否用在了多处加密的地方?秘钥管理方法是否安全? 秘钥是否很久没有更换过? 密钥是否硬编码到了代码中?
是否强制要求加密?例如有的接口通过一个参数来控制加不加密。
是否验证了证书的合法性?
密码是否明文存储的?
是否使用了被弃用的哈希算法?例如 MD5 或 SHA1。是否是需要使用加密哈希算法时使用了非加密哈希算法?
是否使用了已弃用的加密填充方法?例如 PKCS1。
是否使用了已经被废弃的安全协议?例如 web 安全传输协议使用了 SSL。
几点关于敏感数据泄露类注意点
上面主要讲的是加密机制失效导致的数据泄露问题及预防方法,下面再提其他几点数据泄露相关的点:
Web 前端开发中,敏感数据不要存储在本地,所有存储到 Cookie 或者 LocalStorage 里的数据都要进行加密;
生产环境代码中需要去除任何调试代码或接口,去除为调试做的各种日志输出;
安全地处理失败的身份校验,如使用“用户名或密码错误”来提示失败而不是使用“密码错误”,防止泄露过多信息;
接口 Response Headers 里面禁止包含 Web Server 的信息,接口 Response 禁止返回调试信息、程序异常堆栈信息和注释信息;
敏感信息展示时,如果是展示在 web 页面上,后端接口返回数据时需要对敏感字段进行脱敏处理。
2.5、注入类漏洞 🥇🥇🥇
注入(Injection)类漏洞是 Web 安全领域中最常见的攻击方式,注入攻击发生在当不可信的数据作为命令或者查询语句的一部分被发送给解释器的时候。攻击者发送的恶意数据可以欺骗解释器,导致解释器执行了非预期的命令。通俗一点来讲就是把用户输入的数据当作了代码执行。
发生注入类攻击需满足两个关键条件
用户能够控制输入;
程序原本要执行的代码拼接了用户输入的数据。
常见的注入类漏洞及预防措施
常见的注入攻击一般发生在执行 SQL 语句、执行 NoSQL 语句、执行系统命令、ORM 使用、在 LDAP 目录中执行查找、生成要发送到 Web 浏览器的 HTML 页面等场景中。
注意避免Xml 注入、代码注入、SQL 注入、HTML 注入等注入型安全问题的发生,一定要在数据拼接的地方进行安全检查,对拼接内容进行严格校验和必要的转义处理;
禁止字符串拼接 SQL 访问数据库,最好使用SqlServer/MySQL 预编译语句,绑定变量方式,DB 层方法禁止传入拼接好的 Sql 语句;
对接口参数进行严格校验,包括是否必传、类型、长度、格式、范围等;
前端页面对用户的输入进行过滤,通过将
<>、''、""等字符进行转义,移除用户输入的Style节点、Script节点、Iframe节点等;根据输出数据所在的上下文来进行相应的编码。数据放置于 HTML 元素中,需进行 HTML 编码,放置于 URL 中,需要进行 URL 编码。此外,还有 JavaScript 编码、CSS 编码、HTML 属性编码、JSON 编码等等;
给 Cookie 设置 HttpOnly 和 Secure 属性,HttpOnly 属性使 Js 脚本无法读取到 Cookie 信息,Secure 属性限制 Cookie 只允许 Https 协议的请求使用。
预防注入类攻击的最好方法是代码审核,可以将静态的(SAST)、动态的(DAST)和交互式(IAST)的安全测试工具集成到 CI/CD 流程中,以便在部署到生产环境之前检测出并解决掉注入类安全问题。
参考文档:SQL 注入简介
2.6、不安全的设计类漏洞(Insecure Design)
如何理解不安全的设计类漏洞?
不安全的设计(Insecure Design)漏洞主要指在系统设计和架构设计中,由于不恰当的设计导致的安全风险。不安全的设计类漏洞种类非常多,使用一句话来说就是控制机制缺失或控制机制失效。需要注意不安全的设计和不安全的实现的区别,因为它们有不同的原因和预防措施。即使安全的设计,在实现过程中仍然可能出现漏洞。不安全的设计即使完美得被实现出来,也依然是有问题的,因为在设计过程中就没有考虑针对特定攻击的安全防范措施。之所以会出现不安全设计类漏洞,主要是因为缺少对系统风险的充分分析,无法做出对应的安全设计。
不安全的设计类漏洞预防措施
建立并使用安全开发流程,协同专业安全人员进行安全和隐私风险评估;
建立并使用安全设计模式库;
为系统(特别是关键的业务逻辑、访问控制逻辑、授权和鉴权等)面临的威胁建立模型,明确可能来自的攻击有哪些方面;
使用代码静态分析工具和动态分析工具来扫描程序的安全漏洞;
编写单元和集成测试以验证所有关键流程都能抵抗威胁模型。
2.7、认证及验证机制失效类漏洞(Identification and Authentication Failures)🥇🥇🥇
如何理解认证及验证机制失效类漏洞?
应用程序通过网络要证明一个人的身份的话,就需要这个人的私密且唯一的东西,比如账号密码。绝大多数系统只要你提供了账号密码,就可以确定这个人是你。使用账号密码登录成功后,服务器会下发一个 Token(登录凭证),接下来的操作只要带上这个 Token 就可以了。
认证及验证机制失效(Identification and Authentication Failures)类漏洞基本也都发生在登录和校验 Token 的地方,由于在确认用户身份、用户身份认证、会话管理过程中因逻辑漏洞或使用了不当的机制导致了安全漏洞的出现。下面列举几个典型案例
撞库攻击,攻击者通过收集互联网上已经泄露的账号和密码信息,生成对应的字典表,尝试批量登录其他网站后,得到一系列可以登录的用户。如果程序没有做对应的应对措施,就会导致用户数据泄露;
大多数的认证攻击是因为应用程序只使用密码作为登录的唯一因素,如果没有多因子认证,就很容易被攻击;
应用程序的会话超时时间设置不合理。如果一个用户使用公用电脑登录一个网站系统后,用户没有选择“登出”系统而只是关闭了浏览器就离开的话,即使过一段时间攻击者仍然可以打开此电脑的同一个浏览器访问同一个网站来获取此用户的数据,因为用户的账号仍然处于通过认证的状态。
避免出现认证及验证机制失效类漏洞产生需要注意的点
- 开启多因子认证来防止自动化撞库攻击、暴力破解和被盗的凭证重用攻击;
不要在发布或部署应用程序时设置默认账号密码,特别是管理员身份的账号;
- 提高密码的复杂度,例如要求密码长度 8 位以上,区分大小写字母,为大写字母、小写字母、数字、特殊符号中两种及以上的组合,不要有连续的字符(比如 1234abcd),尽量避免出现重复的字符(比如 1111);
安全地处理失败的身份校验提示,如使用“用户名或密码错误”提示登录失败而不是使用密码错误或者账号不存在,防止枚举攻击;
- 登录失败后,限制登录尝试频率并逐渐延长可以重试的间隔时间,检测到撞库攻击或暴力破解时,记录下来异常行为并给对应负责人发报警信息;
对登录成功后下发的 Token 需要保证足够的随机性,比如采用足够强的随机数生成算法生成 Token,用户登录完成后要生成新的 Token 并且给 Token 设置一个合理的有效期(例如十分钟、半个小时、一个小时等,时间不宜过长),Token 要安全保存,用户长时间不操作或者退出系统要销毁 Token;
在执行关键操作(如修改密码、更改手机号或邮箱)时,需要对用户身份进行二次验证。
2.8、软件和数据完整性故障类漏洞(Software and Data Integrity Failures)🥇🥇🥇
如何理解软件和数据完整性故障类漏洞?
在程序开发过程中,难免会使用到三方库、插件、模块等,对应的文件很多可能是存储在公共平台上的,例如 Github、Gitlab、Gitee 等,所以使用这些资源的时候校验它们的完整性尤为重要。
当程序中使用用户提交的数据或者从三方获取的数据时,如果缺少对数据完整性的校验,也很容易出现安全问题。
安装或更新软件,没有校验软件的完整性或签名,这种情况也是很容易出现安全问题的。
当程序中整合了三方库、插件、模块等资源时、使用关键数据时、在安装或更新软件时,因为没有校验完整性而导致的安全漏洞统称为软件和数据完整性故障类漏洞(Software and Data Integrity Failures)。
现在大多数公司采用的软件开发方式大都是敏捷式的,主要特点是快速开发和快速部署。这种情况下尤其要注意对核心组件的完整性校验,如果没有或忘记做完整性校验,攻击者就很容易注入恶意代码和数据。
避免出现软件和数据完整性故障类漏洞产生需要注意的点
使用数字签名或类似的机制来校验软件或数据的来源和完整;
确保依赖库(如 npm、maven、go modules)使用的是可信的仓库。如果是私有的依赖库,确保托管在内网搭建的仓库;
确保使用可靠的工具来检查使用的组件不包含已知漏洞;
对代码和配置更改进行审计;
CI/CD 流程具备访问控制功能,确保构建和部署过程中代码的完整性;
不反序列化不可信的、不完整的和格式错误的数据;
严格校验用户提交的数据或者从三方获取的数据。
2.9、服务器端请求伪造类漏洞(SSRF,Server-Side Request Forgery)
如何理解服务器端请求伪造(SSRF)类漏洞?
当服务器向用户提交的未被严格校验的 URL 发起请求的时候,就有可能会发生服务器端请求伪造(SSRF,即 Server-Side Request Forgery)攻击。
SSRF 是由攻击者构造恶意请求 URL,由服务端发起请求的安全漏洞。攻击者可以利用 SSRF 漏洞来攻击到内部系统,因为服务器请求天然发生在系统内部。SSRF 形成的原因大都是由于服务端提供了从其他服务端应用获取数据的功能,但又没有对目标地址做校验与限制。
应用程序为了给用户提供更多更方便的功能,从另一个 URL 获取数据的场景越来越多,因此 SSRF 漏洞也越来越多。此外,由于云服务和体系结构的复杂性,SSRF 攻击产生的影响也越来越大。
举个例子
假设一个电商网站,展示商品详情的时候也同时展示库存数量,库存数量需要提供商品详情信息的后端服务通过 REST API 查询其他后端服务得到,而其他后端服务的 URL 地址直接包含在查询商品详情的接口中,作为此接口的一个参数。所以展示商品详情界面会发出如下请求:
POST/product/detail HTTP/1.0
Content-Type: application/json
{"productId:66","stockApi":"http://stock.xxx.com/stock/detail"}
这种情况下,攻击者可以通过修改请求参数 stockApi 以指定任意 URL,例如:
POST/product/detail HTTP/1.0
Content-Type: application/json
{"productId:66","stockApi":"http://localhost/admin"}
此时,服务端就会访问 http://localhost/admin 并将其内容返回给用户,攻击者就可以采用这用方式来尝试获取到服务器相关的信息。
如何预防 SSRF 攻击
严格校验用户输入的 URL,可以使用白名单过滤来限制输入,只允许特定的协议、主机和端口;
不要把原始的响应数据直接返回给客户端;
限制 Web 应用程序的网络访问权限,可以让远程资源访问功能使用单独的网络;
限制 Web 应用程序对服务器端资源的访问权限,可以使用访问控制列表(ACL)来限制应用程序可以访问的 URL 和端口;
加强代码审核,通过人工审核和自动化审核工具审核的方式来发现潜在的 SSRF 漏洞。
更多说明请参见微软官方文档:安全和标识
3、⚜️ 服务器
3.1、IIS 相关安全问题
3.1.1、IIS 版本泄露 🥇🥇🥇
如下图所示,部署在 IIS 中的站点就泄露了其版本信息:

为了避免 IIS 版本信息泄露,我们应该将Server从头部信息中去除。
解决办法
下载
iis_stripheaders_module_1.0.5官网地址:https://github.com/dionach/StripHeaders/releases
文件地址:https://github.com/dionach/StripHeaders/releases/download/v1.0.5/iis_stripheaders_module_1.0.5.msi双击安装
iis_stripheaders_module_1.0.5.msi安装完成后,我们双击 IIS 总站点的
模块,会发现多了一个名称为StripHeadersModule的模块,如下图所示:
StripHeadersModule模块 
StripHeadersModule模块 验证
此时,我们不需要重启 IIS 服务,然后再次刷新刚才的站点,即可看到 IIS 的版本信息从头部响应中移除了,如下图所示:

IIS版本信息被移除
3.1.2、IIS X-Powered-By 版本泄露 🥇🥇🥇
X-Powered-By代表站点应用程序类型,如ASP.NET。
为了避免 IIS 应用程序类型信息泄露,我们应该将X-Powered-By从头部信息中去除。
解决办法
方案一
参见 3.1.1、IIS 版本泄露 处理即可。
方案二
在 IIS 中点击某个站点,双击
HTTP 响应标头,然后选中X-Powered-By项后鼠标右键选择删除即可,如下图所示:
X-Powered-By移除 
X-Powered-By移除
3.1.3、X-AspNet-Version 版本泄露 🥇🥇🥇
X-AspNet-Version代表站点使用的应用程序框架版本号(如 Framework 版本号4.0.30319)。
为了避免 IIS 应用程序框架版本信息泄露,我们应该将X-AspNet-Version从头部信息中去除。
解决办法
我们只需要将enableVersionHeader设置为false即可。
途径一
打开 web.config 文件,在
system.web节点下找到httpRuntime节点,在该节点中增加enableVersionHeader="false"即可。<system.web> <httpRuntime targetFramework="4.5" enableVersionHeader="false" /> </system.web>途径二
在 IIS 中点击某个站点,双击
配置编辑器,然后在下拉框中展开system.web节点,然后点击httpRuntime,然后将enableVersionHeader选择为False即可,如下图所示:
X-AspNet-Version移除 
X-AspNet-Version移除 
X-AspNet-Version移除
3.1.4、禁用 ASP.NET 调试 🥇🥇🥇
ASP.NET 支持在特殊调试模式下编译应用程序,以帮助开发人员进行故障排除。调试模式导致 ASP.NET 使用额外信息编译应用程序。该信息使调试器能够密切监视和控制应用程序的执行。在调试模式下编译的应用程序按预期执行。但是,应用程序的性能会受到影响。为了避免对性能的影响,最好仅在开发人员进行交互式故障排除时启用调试。
默认情况下禁用调试。调试经常启用以排查问题。但在问题解决后,它通常不会被禁用。
解决办法
打开 web.config 文件,在system.web节点下找到compilation节点,在该节点中增加debug="false"即可。
<system.web>
<compilation debug="false" targetFramework="4.5" />
</system.web>
更多说明请参见微软官方文档:为 ASP.NET 应用程序禁用调试
3.1.5、点击劫持漏洞 🥇🥇🥇
解决办法
打开 web.config 文件,在system.webServer节点下找到httpProtocol--customHeaders节点,在该节点下增加add节点,并在该节点中增加name="X-Frame-Options"和value="SAMEORIGIN"即可,完整配置如下所示:
<system.webServer>
<httpProtocol>
<customHeaders>
<!--注意:如果设置了下列控制,那么网站的页面在嵌入第三方系统的时候会拒绝-->
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
</system.webServer>
警告
如果设置了上述控制,那么网站的页面在嵌入第三方系统的时候会拒绝访问,效果如下图所示:

3.2、设置账号和密码保护 🥇🥇🥇
账号和密码保护,可以说是服务器系统的第一道防线,目前网络上大部分针对服务器系统的攻击,都是从截获、窃取服务器的账号、密码开始。一旦黑客窃取服务器的账号和密码,并登陆进入系统,那么前面的防护措施几乎就失去了保护作用。
所以对服务器系统管理员的账号和密码进行管理,定期修改密码,是保证服务器系统安全非常重要的防护措施。
定期修改密码的过程中,一定要避免弱口令的出现。
3.3、账户锁定策略 🥇🥇🥇
Windows 通过账户锁定策略,对一定次数的失败登录进行账户锁定。尽管这是一个很容易实施的功能, 它能够很大程度地降低暴力攻击的风险。
3.4、明文密码及其他敏感信息 🥇🥇🥇
系统经常会在一些如域登录脚本,数据库链接字符串文件,以及一些第三方软件生成的文件中存在这明文密码。
在很多情况下,系统在多用户的情况下,如果对这些文件的访问不加控制的话,可能会导致本系统对对其他系统的登录信息泄露,从而导致对那些系统的非法访问。
对企业的新旧系统都需要做检查,以确保明文密码或其他一些敏感信息的访问控制。
3.5、开启 UAC🥇🥇🥇
UAC 全称为 User Account Control,即用户账户控制。是微软操作系统中的一项安全特性。它会在用户尝试运行需要管理员权限的任务、更改系统设置等操作时,通知用户并要求用户提供管理员密码或确认执行此项操作。
UAC 的主要作用是保护系统安全。在以前的 Windows 版本中,当用户拥有管理员权限时,任何程序都可以执行系统级别的操作,这给病毒、恶意软件等程序提供了可乘之机。而 UAC 强制用户在执行这些需要管理员权限的操作之前进行确认,从而减少了系统被攻击的可能性。
需要注意的是,UAC 并不全面保证系统安全。用户在安装新软件时需要仔细阅读安装过程中的提示信息,不要轻易安装安全性未知的软件。另外,在需要管理员权限的情况下,应该保持警惕,不要授权给不信任的程序。
3.6、安装和设置防火墙 🥇🥇🥇
对服务器的安全而言,安装防火墙非常有必要。防火墙对于非法访问具有很好的预防和阻拦作用。但是仅仅安装了防火墙,并不等于服务器就安全了。在安装防火墙之后,需要根据自身的网络环境,对防火墙进行适当的配置,以达到最好的防护效果。
3.7、安装系统补丁 🥇🥇🥇
无论是 Windows、UNIX,还是 Linux,任何操作系统都存在有一定的漏洞,及时为系统打上补丁,避免漏洞被网络黑客蓄意攻击利用,是保障服务器安全的重要举措之一。
国家信息安全漏洞库
关于各种漏洞信息的报告,我们可到 国家信息安全漏洞库 进行详细的阅读!
3.8、关闭不需要的服务和端口 🥇🥇🥇
服务器的操作系统在安装时,会启动一些并不需要的服务,这些服务不仅会占用系统的资源,也会增加系统的安全隐患。
对于一段时间内完全不需要用到的服务器,可以选择完全关闭;对于要使用的服务器,也应该关闭不需要的服务和端口,例如:Telnet(远程终端协议)等。
另外,还要关闭一些没有必要的 TCP 端口。
3.9、安装专门的杀毒软件 🥇🥇🥇
由于计算机复杂的技术和网络环境,导致病毒非常猖獗,这就需要在服务器上安装专门的杀毒软件,来预防和控制病毒的传播。
同时,在使用杀毒软件的过程中,必须要定期或及时升级杀毒软件,并且每天自动更新病毒库。
3.10、定期对服务器进行备份
即使是最好的配置和专门的维护,也无法保证服务器百分之百的安全。程序错误、硬件故障或人为的操作失误,都有可能导致服务器的数据丢失。因此,应该采用适当的备份计划和措施,在服务器的数据不慎发生丢失的情况下,能够利用备份的数据,进行快速恢复。
数据备份有完全备份、增量备份、差异备份、镜像备份”`等多种方式。
建议可参考的备份计划
每月镜像备份,每周完全备份以及每日差异/增量备份;
季度镜像备份,每月完全备份以及每日增量备份。
需要注意的是,为了获得最安全的备份保护,数据应该备份保存在其他外部存储介质上,例如:便携式移动硬盘或者其他服务器,而不是保存在需要备份的服务器上。
3.11、安全配置错误类漏洞(Security Misconfiguration)
安全配置错误类漏洞是指在对应用程序、框架、应用程序服务器、Web 服务器、数据库服务器等执行安全配置时,由于配置不当导致的漏洞。例如使用了有安全缺陷的版本、没有修改默认的帐户密码、给了某些帐户过高的权限、对敏感资源没有做访问控制等等,让攻击者有了可乘之机,可以不经授权就可以访问某些系统数据或使用系统功能。据 OWASP 的统计数据显示,4%的应用程序都发生过各种各样的安全配置错误问题。现代化的的应用程序基本都是高度可配置化的,所以安全配置错误类漏洞会越来越多,在配置使用三方应用程序或自研应用程序时,都需要特别注意避免此类漏洞的产生。
下面列举几个典型案例
应用服务器程序附带的示例应用程序在生产环境中没有删除,示例应用程序本身具有安全缺陷,可能被攻击者利用。假设示例应用程序是管理控制台并且默认帐户密码没有更改的情况下,攻击者可以很轻松使用默认帐户密码登录并管理应用服务器程序;
Web 服务器没有禁用目录遍历,攻击者可以通过遍历目录很容易得获取到服务器上的数据;
应用程序将详细的错误消息(例如堆栈信息)返回给用户,这可能会暴露敏感信息或潜在安全问题。
容易出现安全配置错误类漏洞的场景
在应用程序堆栈的某些部分缺少适当的安全强化,或对系统用户的权限配置不当;
安装或使用了不必要的功能,例如服务器启用了不必要的端口、系统添加了不必要的帐户、给帐户分配了不当的权限等;
没有禁用系统的默认帐户密码或者没有修改默认帐户密码;
程序的错误处理信息或堆栈信息返回给了用户;
升级系统或程序时,禁用了安全功能部分的升级;
应用服务器、应用框架(例如 Struts、Spring、http://ASP.NET)、库、数据库等的安全配置项未设置为安全值;
服务器禁用了安全配置,例如 Web 服务器没有配置支持 HTTPS 协议;
系统或应用程序版本过低,没有及时升级,会有很多安全隐患。
避免出现安全配置错误类漏洞产生需要注意的点
每个环境都应该使用相同的配置,使用不同的凭证。每个环境的配置应该做到自动化,以减少设置新环境产生的安全风险;
安装系统时做到最小化安装,不安装非必要的功能;使用一个应用程序时,删除示例代码和文档;
作为补丁管理流程的一部分,需要及时更新安全说明和更新说明文档;
使用自动化工具和流程来验证所有环境中的配置;
在配置权限时,应当使用“最小权限原则”并使用“默认拒绝”的策略;
秘钥禁止硬编码在代码中,禁止生产环境和非生产环境使用相同的秘钥。
3.12、易受攻击和过时的组件类漏洞(Vulnerable and Outdated Components)
如何理解易受攻击和过时的组件类漏洞?
易受攻击和过时的组件(Vulnerable and Outdated Components)类漏洞看名字就很容易理解,就是使用了具有已知漏洞的组件或者已经过时的组件。由于过时的组件不再被维护,会被发现越来越多的安全漏洞但是漏洞也不会再被修复,就会带来极大的安全隐患。当然,这里的组件不是狭义的组件,可以指代码里面引用的三方库、应用程序、操作系统、数据库、服务器、Linux 内核等等。另外组件在保持最新但是安全配置错误的情况下,也是易受攻击的组件。可以使用如下方法来识别易受攻击和过时的组件
如果该组件不再被供应商维护,这意味着供应商不再为该组件提供安全更新或安全补丁;
如果该组件有很多漏洞已经被公开披露或者存在已知漏洞。
容易出现易受攻击和过时的组件类漏洞的场景
不清楚使用的组件和依赖的组件的版本;
使用了不再被维护的或者已经过时的软件,例如操作系统、应用程序、Web 服务器、数据库、三方库等;
没有定期扫描漏洞或订阅与所使用组件相关的安全情报;
在被暴出漏洞的情况下或有新版本的情况下,没有及时修复或升级系统、框架或依赖库的版本;
软件开发或测试人员没有测试更新、升级或打补丁后的应用程序的兼容性;
应用程序的安全配置没有配置正确。
避免出现易受攻击和过时的组件类漏洞产生需要注意的点
删除使用不到的依赖项、特性、组件和文件;
使用版本控制等工具持续盘点各组件的版本及依赖关系,持续关注使用的组件版本是否出现了安全漏洞;
从官方获取组件,获取到组件后校验签名是否正确,防止被恶意篡改;
定期对使用的组件进行漏洞扫描,及时打安全补丁,有新版本后及时升级;
充分了解各组件的安全配置项,确保配置正确。
3.13、安全日志记录和监控故障(Security Logging and Monitoring Failures)
如何理解安全日志记录和监控故障?
没有安全日志记录和监控并不会直接导致安全问题的发生,但是日志记录和监控非常重要,它们的缺失或故障会直接影响系统可观测性、故障发现时间和故障排查进度,进而给客户和公司造成更多的损失。因此,拥有日志系统和监控系统来收集日志并在发生故障或错误时及时警报并排查问题是非常重要的。
以下几点没做就需要注意了
没有日志或者日志不全,缺少部分记录;
没有记录关键的操作记录,例如用户登录记录、关键操作记录、审计记录等;
日志记录没有备份;
日志记录意思模糊不清;
本地化存储日志,如果服务器出现故障,日志也将随着消失;
没有监控系统或有监控但没有报警;
监控系统的监控任务设置不正确,不能及时报警或报警信息模糊;
报警阈值设置过低,导致狼来的故事重演;
日志系统和监控系统访问控制没做好。
改进措施
上线完善的日志系统;
确保记录所有关键操作记录;
日志记录做好备份;
确保日志是全量的,没有数据缺失;
确保日志包含所有相关数据并使用规范的格式;
上线完善的监控系统;
设置好监控任务后,多测试几次确保配置无误;
确保报警阈值和报警信息设置恰当精准;
确保日志系统和监控系统的安全性,做好访问控制。
传统的加解密的方法大致可以分为三种
↩︎类型 说明 对称加密 即加密方和解密方都使用相同的加密算法和密钥,这种方案的密钥的保存非常关键,因为算法是公开的,而密钥是保密的,一旦密匙泄露,黑客仍然可以轻易解密。常见的对称加密算法有: AES、DES等。非对称加密 即使用不同的密钥来进行加解密,密钥被分为公钥和私钥,用私钥加密的数据必须使用公钥来解密,同样用公钥加密的数据必须用对应的私钥来解密,常见的非对称加密算法有: RSA等。不可逆加密 利用哈希算法使数据加密之后无法解密回原数据,这样的哈希算法常用的有: MD5、SHA-1等。
