【应用安全编码规范】---模板

目录
一. 概述 1
二. 适用范围 1
三. 参考依据 1
四. 安全编码规范 2
4.1 明确安全需求 2
4.1.1 描述说明 2
4.1.2 规范要求 2
4.1.3 防护缺陷 2
4.1.4 实现方案 2
4.2 善用安全框架与组件库 3
4.2.1 描述说明 3
4.2.2 规范要求 3
4.2.3 防护缺陷 3
4.2.4 实现方案 3
4.3 安全数据库访问 4
4.3.1 描述说明 4
4.3.2 规范要求 4
4.3.3 防护缺陷 5
4.3.4 实现方案 5
4.4 数据编码和转义 6
4.4.1 描述说明 6
4.4.2 规范要求 7
4.4.3 防护缺陷 7
4.4.4 实现方案 8
4.5 验证所有输入 10
4.5.1 描述说明 10
4.5.2 规范要求 10
4.5.3 防护缺陷 10
4.5.4 实现方案 11
4.6 实现身份标识、身份验证和会话管理控制 15
4.6.1 描述说明 15
4.6.2 规范要求 15
4.6.3 防护缺陷 17
4.6.4 实现方案 18
4.7 实施访问控制 22
4.7.1 描述说明 22
4.7.2 规范要求 23
4.7.3 防护缺陷 23
4.7.4 实现方案 24
4.8 数据保护 25
4.8.1 描述说明 25
4.8.2 规范要求 25
4.8.3 防护缺陷 27
4.8.4 实现方案 27
4.9 建立日志审计与入侵检测 28
4.9.1 描述说明 28
4.9.2 规范要求 29
4.9.3 实现方案 29
4.10 处理所有错误与例外 30
4.10.1 描述说明 30
4.10.2 规范要求 31
4.10.3 实现方案 31
4.10.4 参考案例 32

一.概述
基于SDL流程,代码开发阶段需要遵守相应的编码规范约束,以达到减少其安全缺陷到可接受范围的目的。考虑到编程开发的技术革新较快,开发人员需灵活参考本规范,取其意,而非流于表象。养成良好的编程习惯,落地实施,切实改善系统的安全性,有效提升系统的自身健壮度,保障业务安全有效开展。
二.适用范围
本规范依据应用安全设计需求及OWASP最佳实践,对编码过程中常见的安全风险提出安全控制建议,并通过说明和举例,指导开发人员进行安全编码控制。适用于xx汽车有限公司一般性信息系统的软件研发类项目的安全管理规范。本规范所涉及的文档,流程仅限于xxIT科的项目运作指导使用,本规范最终解释权归xxIT科所有。
三.参考依据
OWASP Application Security Verification Standard
OWASP Top Ten 2017
《GBT 38674-2020 信息安全技术 应用软件安全编程指南》
OWASP_SCP_Quick_Reference_Guide
《计算机软件开发规范》 GB/T 8566-2007
《信息安全管理要求》 ISO/IEC27001
四.安全编码规范
4.1明确安全需求
4.1.1描述说明
安全需求是针对软件系统开发生命周期中的安全问题的需求说明,确保满足软件的不同安全属性。安全需求来自安全运维工程师提供的《应用安全需求表》以及《应用安全设计规范》中对应的要求。开发人员亦可直接参考《应用安全设计规范》来明确安全需求。
安全需求为应用程序提供了审查安全功能的基础。不同于针对各应用程序设置和实现相对应的安全方法,安全需求作为开发人员重要的标准和安全测试的依据,检验开发人员是否依据安全需求进行正确的实现产品安全功能。另外这些经过审查和验证的安全需求,将持续为产品开发过程中所遇到的安全问题提供和优化解决方案,防止重复发生,并积累成果。
4.1.2规范要求
根据项目组确定的软件系统安全需求,结合SDL安全开发周期管理要求及技术框架,设计和实现安全控制措施;
在开发过程中,约束开发人员依照对应开发语言的编码规范要求正确实现安全编码。
安全需求作为需求提出方与实施方之间的契约,实施方(开发团队)在交付时,需求提出方依据安全需求对实施方进行安全检查。
4.1.3防护缺陷
依据安全需求定义来预防缺陷,安全需求定义应用程序的安全功能,从应用程序生命周期的开始就融入了安全,从而使漏洞减少到可接受范围。
4.1.4实现方案
成功使用安全需求包括四个步骤,包括识别、记录、实现,然后确认应用程序中新的安全特性和功能的正确实现。
安全审查
开发人员根据安全需求审查现有应用程序,以确定应用程序当前是否满足需求;或者是否需要设计和实现相应的安全控制机制。
实现和验证
在确定安全开发需求之后,开发人员必须按照安全开发需求开发或修改应用程序,以添加新功能或消除不安全功能。在此阶段,开发人员需按照SDL流程先根据需求输出设计方案,然后根据设计方案编码实现需求,最后通过创建测试用例来确认需求设计是否实现。
4.2善用安全框架与组件库
4.2.1描述说明
开发Web应用或者移动端应用程序时,防护措施从头到尾自行设计并实现耗时巨大且会存在许多安全漏洞。业界有许多成熟的安全框架可以帮助开发过程中减少安全漏洞。
规范要求
使用经测试和可信的框架代码开发应用程序;
使用安全框架时要随时保持该框架的最新版本,避免遭受已知威胁攻击;
在引入第三方开源组件时,应充分评估当前版本是否存在已知漏洞,在应用的架构层面对组件功能进行封装,方便调用,在组件发现漏洞时,也便于替换和升级;
组件之间通过安全机制进行隔离,如网络分离、防火墙规则或基于云的安全组。
4.2.2防护缺陷
安全框架通常可以避免常见的网站风险,例如 OWASP Top 10,特别是基于错误输入的攻击方式 (例如输入JavaScript而非使用者名称)。
4.2.3实现方案
建议依据目前现有的架构,采用合适的安全框架。如:
Spring Security(Java)
Apache Shiro(Java)
Django Security(Python)
Flask security(Python)
另外如采用第三方开发团队,开发团队需要举证框架的先进性。还必须考虑框架是否存在潜在安全的漏洞、网站提供功能的攻击路径以及第三方插件漏洞等安全问题。在引入框架或组件时,可通过官方消息、CVE、CNNVD、配置检查工具进行检测是否存在安全漏洞:
Dependency-Check:https://www.owasp.org/index.php/OWASP_Dependency_Check
Retire.js:http://retirejs.github.io/retire.js/
参考案例
案例1:Wordpress框架
Wordpress框架是一个很普遍的网站框架,可以快速的搭建网站,也支持安全漏洞的更新,但是 Wordpress 第三方工具却不一定会有安全补丁的实时更新。因此,建议额外的安全防护措施,如经常更新安全补丁、尽早验证等措施还是必要的。
4.3安全数据库访问
4.3.1 描述说明
本节描述对所有数据存储的安全访问规范,包括但不限于关系型数据库和非关系型数据库。需要考虑的一些方面的安全要求:
安全查询
安全配置
安全认证
安全通信
4.3.2 规范要求
安全查询
应避免不可信的数据输入成为SQL语句的一部分,设计上最好实现参数化查询。
安全配置
开发过程中所使用的数据库服务,应按照上线运维环境的安全配置进行管理,确保数据库管理系统(DBMS)和托管平台上可用的安全控制被启用和正确配置。对于最常见的DBMS,可参考相应安全配置基线进行配置。
安全认证
对数据库的所有访问都应该经过正确的身份验证。
安全通信
应对数据流进行加密、提供对数据完整性的检查。
4.3.3 防护缺陷
注入
注入缺陷非常普遍,特别是在遗留代码中。注入漏洞通常存在于SQL,LDAP,XPath或NoSQL查询,OS命令,XML解析器,SMTP标头,表达式语言和ORM查询中。
弱服务器端控件(移动客户端)
服务或API调用若没有依据安全编码要求正确实现,也会在服务器中产生OWASP Top 10漏洞。攻击者通过移动界面或者客户端发起的请求,对服务器开展恶意攻击。
4.3.4 实现方案
安全查询
SQL 注入是最危险的Web应用程序的风险之一,且有较多的自动化攻击工具供攻击者使用,如SQLMap、pangolin等。通过SQL注入将恶意SQL代码注入到Web应用程序时,可以造成整个数据库被窃取删除或修改,甚至可结合数据库的特性来获取运行数据库的主机的控制权限。导致SQL注入最主要的原因在于将 SQL 查询语句与参数的输入拼接在一个查询字符串中。
要避免SQL注入的攻击,必须要避免不可信的数据输入成为SQL语句的一部份。设计上最好的防护方式就是实现参数化查询,将SQL语句与参数分离后送到数据库处理。
在ASP、ColdFusion、c#、Delphi、.net、Go、Java、Perl、PHP、PL/SQL、PostgreSQL、Python、R、Ruby和Scheme中查询参数化示例可参考:
http://bobby-tables.com
Query_Parameterization_Cheat_Sheet:https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet。
参数化查询注意事项
数据库查询中的某些位置是不可参数化的,对于不同的数据库供应商,这些位置是不同的。当遇到无法绑定到参数化查询的数据库查询参数时,一定要进行精确匹配验证或手动转义。
此外,虽然参数化查询的使用在很大程度上对性能有积极影响,但特定数据库实现中的某些参数化查询将对性能产生负面影响,因此需要测试查询的性能,特别是具有大量子句或文本搜索功能的复杂查询。
安全配置
开发过程中所使用的数据库服务,应按照上线运维环境的安全配置进行管理,确保数据库管理系统(DBMS)和托管平台上可用的安全控制被启用和正确配置。对于最常见的DBMS,可参考相应安全配置基线进行配置。
安全认证
对数据库的所有访问都应该经过正确的身份验证。
对DBMS的身份验证应该以安全的方式完成。
身份验证应该只在安全通道上进行。
凭据必须有适当的安全保护并可供使用。
安全通信
大多数DBMS支持各种通信方法(服务、api等)——安全(经过身份验证、加密)和不安全(未经身份验证或未加密),根据Protect Data Everywhere控件仅使用安全通信选项是一种很好的做法。
4.4 数据编码和转义
4.4.1 描述说明
编码和转义是防止注入攻击的防御技术。编码(通常称为“输出编码”)涉及将特殊字符转换成某种不同但等效的形式,在目标解释器中不再危险,例如将“<”字符转换为&lt写入HTML页面时的字符串。转义包括在字符/字符串前添加一个特殊字符,以避免被误解,例如,在“”(双引号)字符前添加一个“\”字符,以便将其解释为文本,而不是关闭字符串。
输出编码最好在内容传递给目标解释器之前应用。如果在处理请求时过早执行了这种防御,那么编码或转义可能会干扰程序其他部分内容的使用。例如,如果在将数据存储到数据库中之前将HTML内容转义,然后UI会再次自动转义该数据,那么由于双转义,内容将无法正确显示。
4.4.2 规范要求
向HTML页面输出用户数据前须对常见危险字符(比如:\、'、"、…、/、\r、\n、<、>、^、|、!、`、、(、)、&、;、 -、:、%等漏洞利用字符)进行安全过滤或转义编码;
对于通过输入/输出脏数据引起语义变化、漏洞特征可枚举的攻击,应在编码时进行针对性防护。
4.4.3 防护缺陷
注入
注入缺陷非常普遍,特别是在遗留代码中。注入漏洞通常存在于SQL,LDAP,XPath或NoSQL查询,OS命令,XML解析器,SMTP标头,表达式语言和ORM查询中。
SQL注入:特征为拼接SQL参数,可利用预处理等方式进行防护(比如:使用参数化查询方式,利用PreparedStatement对象SET方法给参数赋值),使传入数据不作为SQL语句一部分被执行;
XML注入:特征为拼接来自请求中的数据,可通过编码或转义<、>等字符进行防护;
XML外部实体注入:特征为解析XML时未禁止解析DTDs,可通过编码、转义XML外部实体或直接禁止DTDs解析进行防护;
LDAP注入:特征为拼接用户可控的输入参数,可通过对\、
、(、)等符号进行编码或转义进行防护;
命令注入:特征为拼接用户可控的命令参数,可通过编码或转义命令管道符(比如|)等方式进行防护;
路径遍历漏洞:特征为文件路径中拼接用户可控的参数,可通过编码或转义…/、…\、…等字符进行防护;或者通过判断文件真实路径是否属于有效目录的方式进行防护,如Java代码File类的getCanonicalPath()获取真实路径;
CRLF漏洞:特征为输出参数中引入\r\n导致(说明:该漏洞也称HTTP响应分割漏洞,当服务器端将未经验证的从请求中获取到的数据直接写入到HTTP Header中时,攻击者可通过控制传入的数据添加CR(回车,由%0d或\r提供)和LF(换行,由%0a或\n提供),导致响应的数据分割为两种不同的HTTP响应输出流,攻击者可通过此漏洞进行跨站脚本或者缓存投毒攻击),可通过编码或转义\r、\n字符的方式进行防护。
跨站脚本(XSS)
XSS是OWASP Top 10中第二大流行问题,在所有应用程序中约占三分之二。
客户端注入(移动客户端)
客户端注入导致通过移动应用程序在移动设备上执行恶意代码。
4.4.4 实现方案
上下文编码输出
上下文输出编码是阻止XSS所需的一种关键的安全编程技术。在构建用户界面时,在动态地将不可信数据添加到HTML之前的最后一刻,将对输出执行这种防御。编码的类型将取决于显示或存储数据的文档中的位置(或上下文)。用于构建安全用户界面的不同编码类型包括HTML实体编码、HTML属性编码、JavaScript编码和URL编码。
安全编码组件
安全组件 访问地址
owasp Java编码组件 https://www.owasp.org/index.php/OWASP_Java_Encoder_Project
antixssencoder https://docs.microsoft.com/en-us/dotnet/api/system.web.security.antixss.antixssencoder?redirectedfrom=MSDN&view=netframework-4.7.2
zend Escaper -上下文编码 https://framework.zend.com/blog/2017-05-16-zend-escaper.html
参考案例
案例1:Java编码
有关提供上下文输出编码的OWASP Java编码器的示例,请参阅:https://www.owasp.org/index.php/OWASP_Java_Encoder_Project#tab=Use_the_Java_Encoder_Project。
案例2:net编码
从.NET 4.5开始,反跨站脚本库成为框架的一部分,但默认情况下不启用。您可以指定使用此库中的AntiXssEncoder作为使用web的整个应用程序的默认编码器并配置设置。应用对于输出的上下文编码很重要——这意味着使用AntiXSSEncoder库中的正确函数来获得文档中数据的适当位置。
案例3:PHP编码
在Zend Framework 2 (ZF2)中,Zend\Escaper可以对输出进行编码。有关上下文编码示例,请参阅https://framework.zend.com/blog/2017-05-16-zend-escaper.html。
案例4:其他类型的编码和注入防御
编码/转义
编码/转义可用于中和内容以对抗其他形式的注入。例如,在向操作系统命令添加输入时,可以中和某些特殊的元字符。这被称为“OS命令转义”、“shell转义”或类似。这种防御可以用来阻止“命令注入”漏洞。
还有其他形式的转义可用于防御注入攻击,例如XML属性转义停止各种形式的XML和XML路径注入,以及可用于停止各种形式的LDAP注入的LDAP专有名称转义。
转义前
在这里插入图片描述

转义后
在这里插入图片描述

字符编码和规范化
Unicode编码是一种存储具有多个字节的字符的方法。只要允许输入数据,就可以使用Unicode输入数据来伪装恶意代码并允许各种攻击。RFC 2279引用了许多编码文本的方法。
规范化是一种系统将数据转换为简单或标准形式的方法。Web应用程序通常使用字符规范化来确保所有内容在存储或显示时都是相同的字符类型。
4.5 验证所有输入
4.5.1 描述说明
任何跟应用系统有直接或是间接或是交互影响的数据输入都应该被视为不可信的,因此应用程序对于数据的输入应该验证其合法性与语意的正确性,也包含要显示给用户的输出内容。除此之外,安全的应用系统会将所有的参数视为不可信任并且针对所有的参数进行安全防护控制和语法检查。
举例来说,应用程序可能只允许用户选择四位数字的 accountID 来进行操作,该应用系统应该假设用户会输入 SQL injection 的恶意攻击,并且做数据输入的检查来确认该数据是否为四位数字而且输入的字符只有数字。语意的检查主要在于检查资料是否有意义,例如上述范例,应用程序应该假设用户会输入一个不允许登入的accountID,因此应用程序必须要检查该用户accountID是否有权限存取。
输入验证必须要在服务器端发生。客户端的数据验证检查可能使用上比较方便,例如客户端的检查可以透过 JavaScript 验证直接告诉用户数据输入的正确性,但是服务器端的检查还是必须的,因为单纯靠客户端的检查,很容易被黑客绕过而对服务器直接进行攻击。
4.5.2 规范要求
系统接受用户数据输入时,应对输入的关键参数做合法性验证,包括但不限于验证数据的类型、长度、格式和范围等;
系统接受用户数据输入时,应对关键客户信息在服务器端再次进行格式和类型的检测。
4.5.3 防护缺陷
一定程度上防止XSS、SQL注入和其他攻击。
SQL注入:特征为拼接SQL参数,可利用预处理等方式进行防护(比如:使用参数化查询方式,利用PreparedStatement对象SET方法给参数赋值),使传入数据不作为SQL语句一部分被执行;
XML注入:特征为拼接来自请求中的数据,可通过过滤<、>等字符进行防护;
XML外部实体注入:特征为解析XML时未禁止解析DTDs,可通过禁止DTDs解析进行防护;
LDAP注入:特征为拼接用户可控的输入参数,可通过对\、*、(、)等符号进行过滤或转义进行防护;
命令注入:特征为拼接用户可控的命令参数,可通过过滤命令管道符(比如|)等方式进行防护;
路径遍历漏洞:特征为文件路径中拼接用户可控的参数,可通过过滤…/、…\、…等字符进行防护或者通过判断文件真实路径是否属于有效目录的方式进行防护;
CRLF漏洞:特征为输出参数中引入\r\n导致(说明:该漏洞也称HTTP响应分割漏洞,当服务器端将未经验证的从请求中获取到的数据直接写入到HTTP Header中时,攻击者可通过控制传入的数据添加CR(回车,由%0d或\r提供)和LF(换行,由%0a或\n提供),导致响应的数据分割为两种不同的HTTP响应输出流,攻击者可通过此漏洞进行跨站脚本或者缓存投毒攻击),可通过过滤\r、\n字符的方式进行防护;
跨站脚本(XSS):XSS是OWASP Top 10中第二大流行问题,在所有应用程序中约占三分之二。可通过过滤<、>、/、“、script、alert等。
4.5.4 实现方案
黑名单和白名单
对于数据输入的验证,常见的有两种方式,一种是黑名单另外一种是白名单:
黑名单主要检查使用者输入是否在已知的恶意输入清单中,主要用于输入数据范围不确定的场景,黑名单的方式比较接近防病毒软件的运作方式:提供第一线的防护,防病毒软件检查如果有已知的病毒档案就进行阻挡。这样的防护方式为防护的基础。比如:在可自由输入的文本框过滤SQL关键字、HTML标签、单引号、双引号等。
白名单主要检查使用者的输入是否是落在已知的合法输入。举例来说,网站可能允许选择三个城市,应用系统就会检查这三个城市是否在合法的白名单中,如果输入的是其他城市就会被拒绝。根据字符合法性检查的白名单会验证使用者输入是否只有包含已知合法字符或是已知的格式。举例来说,使用者名称仅能包含英文字母与只有两个数字的组合。
实现安全的应用系统,白名单的方式通常是比较安全的防护。黑名单的方式比较容易会有错误与误判的情况发生,黑名单需要因为新的攻击不断的更新。
客户端和服务器端验证
为了安全起见,必须始终在服务器端执行输入验证。虽然客户端验证对功能和某些安全目的都很有用,但它通常很容易被忽略,这使得服务器端验证对于安全性更加重要。例如,JavaScript验证可能会提醒用户,特定字段必须由数字组成,但服务器端应用程序必须验证所提交的数据仅由该特性的适当数字范围内的数字组成(注:服务端验证会增加性能开销)。
安全组件/安全机制

安全组件/机制地址
owasp Java HTML Sanitizerhttps://www.owasp.org/index.php/OWASP_Java_HTML_Sanitizer
java JSR-303/JSR-349 Bean验证https://beanvalidation.org/
java Hibernate验证器http://hibernate.org/validator/
jep -290反序列化安全http://openjdk.java.net/jeps/290
apache Commons Validatorhttps://commons.apache.org/proper/commons-validator/
php的过滤函数https://secure.php.net/manual/en/book.filter.php

参考案例
案例1:正则表达式
正则表达式提供数据是否符合格式的一种方式,这是一种有效建立白名单验证的方式。
当使用者注册网站的时候,网站会需要用户名称、密码与电子邮件等信息。黑客有可能透过这些数据,输入恶意的数据。通过正则表达式的验证方式,可以让白名单的检查更有效果:
Email地址:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]
或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=])?$
手机号码:^(13[0-9]|14[0-9]|15[0-9]|166|17[0-9]|18[0-9]|19[8|9])\d{8}$
电话号码(“XXX-XXXXXXX”、“XXXX-XXXXXXXX”、“XXX-XXXXXXX”、“XXX-XXXXXXXX”、"XXXXXXX"和"XXXXXXXX):^((\d{3,4}-)|\d{3.4}-)?\d{7,8}$
国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
18位身份证号码(数字、字母x结尾):^((\d{18})|([0-9x]{18})|([0-9X]{18}))$
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):1[a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):2\w{5,17}$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.
\d)(?=.[a-z])(?=.[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
举例来说,我们利用正则表达式建立使用者检查如下:
3{3,16}$
这个正则表达式的数据输入只允许小写字母、数字、下划线,使用者名称仅限于 3-16 个长度的字母。
正则表达式在应用过程中,需考虑如下问题。

问题描述
潜在的拒绝服务不好的正则表达式的设计会导致 DOS 的攻击。建议在建立这样的白名单时,可以使用正则表达式的测试工具协助开发时进行相关的测试。
复杂性正则表达式只是完成验证的一种方法。对于某些开发人员来说,正则表达式很难维护或理解。其他验证方法包括以编程方式编写验证方法,这对一些开发人员来说更容易维护。

案例2:输入验证限制
数据输入的验证无法完全有效地让所有的输入数据变成安全的,因为很可能白名单字符中也包含潜在恶意的字符,应用程序必须额外采用其他的防护措施。
举例来说,如果要输出 HTML 内容,就必须要做 HTML 编码以防止 Cross-Site Scripting 攻击;如果要透过 SQL 语句执行,就必须使用参数化查询 Query Parameterization 的方式;针对 XSS 或是 SQL injection 的攻击方式都无法靠单纯的数据输入验证来达到完整安全防护。
案例3:验证序列化数据
某些形式的输入非常复杂,以至于验证只能最低限度地保护应用程序。例如,反序列化不受信任的数据或可由攻击者操纵的数据是危险的。惟一安全的体系结构模式是不接受来自不可信源的序列化对象,或者只对简单数据类型进行有限的反序列化。应该避免处理序列化的数据格式,并尽可能使用更简单的方法来保护JSON等格式。
如果不可能,那么在处理序列化数据时需要考虑一系列验证防御:
实现序列化对象的完整性检查或加密,以防止恶意对象创建或数据篡改;
在对象创建之前的反序列化过程中强制执行严格的类型约束,一般会有一组可定义的类;
隔离可反序列化的代码,使其在权限非常低的环境中运行,例如临时容器;
记录反序列化过程中异常和失败,比如传入类型不是预期类型,或者反序列化抛出异常;
限制或监控来自反序列化的容器或服务器的传入和传出网络连接;
监控反序列化,并提醒用户是否不断反序列化。
案例4:处理意外的用户输入
一些框架支持将HTTP请求参数自动绑定到应用程序使用的服务器端对象,此自动绑定功能可以允许攻击者更新不应修改的服务器端对象,攻击者可以使用此特性修改其访问控制级别或绕过应用程序的预期业务逻辑。
这种攻击有许多名称,包括:批量分配、自动绑定和对象注入。
作为一个简单的示例,如果用户对象具有指定应用程序中用户权限级别的字段特权,恶意用户可以查找修改用户数据的页面,并向发送的HTTP参数add privilege=admin。如果以不安全的方式启用了自动绑定,则服务器端对象将被修改利用。
有两种方法可以处理这个问题,详情可参考OWASP Mass_Assignment_Cheat_Sheet:https://www.owasp.org/index.php/Mass_Assignment_Cheat_Sheet
避免直接绑定输入,而是使用数据传输对象。
启用自动绑定,但为每个页面或功能设置白名单规则,定义哪些字段允许自动绑定。
案例5:验证和清理HTML
对于需接受用户输入HTML的应用程序,引入富文本输入控件(如:WYSIWYG编辑器、CKEditor控件),是无法通过直接的验证或转义的:
正则表达式的表达能力不足以理解HTML5的复杂性;
编码或转义HTML会导致HTML不能正确呈现。
为保证输入富文本内容的安全,应用程序在引入富文本控件时,应通过解析和清理HTML格式文本的安全库对内容进行过滤。可参考:https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)Prevention_Cheat_Sheet#RULE.236_-_Sanitize_HTML_Markup_with_a_Library_Designed_for_the_Job。
案例6:使用库和框架中的验证功能
所有语言和大多数框架都提供验证数据的库或函数。验证库通常包括常见数据类型、长度要求、整数范围、“is null”检查等等。开发过程中许多验证库和框架允许定义自己的正则表达式或逻辑以进行自定义验证。具有此功能的例子包括PHP的过滤器函数或Java的Hibernate验证器。HTML Sanitizer的例子包括Ruby on Rails sanitize方法、OWASP Java HTML Sanitizer或DOMPurify。
4.6 实现身份标识、身份验证和会话管理控制
4.6.1 描述说明
数字身份是用户(或其他主体)进行在线操作时的唯一标识。身份验证是验证个人或实体是谁的过程。会话管理是服务器维护用户身份验证状态的过程,使用户可以在不重新验证的情况下继续使用系统。
Digital Identity Guidelines(身份验证和生命周期管理)为实现数字身份、身份验证和会话管理控制提供了可落地的实践指导:https://pages.nist.gov/800-63-3/sp800-63b.html。
4.6.2 规范要求
身份标识
系统应在注册时为用户分配一个系统唯一且用户不可修改的唯一标识符,采用用户名和用户标识符标识用户身份。
身份验证
应用系统应同时采取两种或两种以上组合的不同种类的鉴别技术来实现身份鉴别。比如用户名/口令与CA证书的组合身份认证,这样在很大程度上增加了非授权用户对身份鉴别信息进行攻击的难度,更有效地防止非法入侵;
在发生重要操作(密码修改、撤销操作等)时,应用系统应提供进一步的鉴别机制,如不同的交易口令,以确保发生重要操作的主体为合法用户;
限制登录次数:如采用用户名/口令的方式登录是,连续10次登录均失败,账户将被锁定半小时,超过该时间后账户自动解锁,账户恢复正常;
对身份鉴别数据进行保密性和完整性保护,如使用安全哈希算法(sha256、SM3等)对用户密码信息加盐后进行哈希处理,再存入数据库;
禁止在Cookie中存放用户敏感信息,如密码等信息,避免客户端浏览器缓存用户名、密码等账户信息,所导致的信息泄露;
用户登录系统后,首页面应以明显的方式提示该用户最近的一次成功或不成功的登录日期、时间和IP地址;
登录界面和关键用户交互界面应加上验证码模块,通过人机交互和服务端对验证码的校验,防止暴力破解;
制定密码策略,并应用到用户密码设置功能中。例如:普通用户的密码长度至少8位,最多不超过20位;重要管理员的口令至少在12位以上;密码复杂度应至少包含三种字符;
系统密码找回或重置时,必须通过注册预留的手机号或邮件信息找回或重置;
应保证短信验证码的安全,例如:开通手机动态密码时,系统应验证用户身份并登记手机号码;更改手机号码时,系统应对用户的身份进行验证;手机动态密码应随机产生,手机动态密码长度应不少于4位,由数字和字母组成,手机动态密码应具有有效时间,最长不超过5分钟,超过有效时间未使用应立即作废;
用户提交相关信息更改过程中需要二次认证,具体哪些信息更改需要进行二次认证需要根据业务来进行判断,必要时需要柜台办理。
会话管理
系统从HTTP与HTTPS之间切换时,应更新会话标识;
根据request.getScheme()获取到请求方式,设立会话标识,和之前的会话标识做对比,如果不同则抛出异常;
会话标识(session)字符串推荐128位长,避免暴力散列攻击;
会话标识字符串必须具有随机性和不可预测性,会话标识(session)字符串的长度至少为128位,以增加会话标识符被暴力猜测的难度;
系统验证客户端数据同时应对会话标识进行验证;
登录后把用户uuid注入session中更新session,在操作之前验证当前会话是否已登出或者登录失败,否则操作失败。在每次注销时后需要进行session删除操作request.getSession().invalidate();
系统使用Cookie时,应设置Cookie的Secure属性,不在非SSL通道中传输cookie值;
设置Cookie的Secure属性,不在非SSL通道中传输Cookie值,有效防止中间人攻击等攻击;
若网站使用了HTTPS,还应该给Cookie设置Secure属性,避免Cookie在HTTP 连接中明文传输;
系统应显示用户上一次成功的会话建立的日期、时间、方法(PC端、安卓端或者IOS端);
系统应显示用户上一次不成功的会话建立的日期、时间、方法(PC端、安卓端或者IOS端);
对用户请求登录验证密码后记录下用户的日期、时间和方法,以及密码校验的结果;
系统应对页面来源进行检测,严格限制页面间的前后访问继承关系,对于重要过程可通过标识的方法进行控制;
对于重要的页面访问,可以在请求时服务端校验referer字段,判断请求是否上级链接url页面进入的;
系统限制页面访问来源时,通过referer信息进行判断,也可通过设置页面令牌散列的方式判断;
系统中对于关键业务操作应确保使用浏览器“后退”功能无法回到上一步操作界面;
系统应限制整体的并发会话和单用户并发会话的最大数目。需要在web-server配置;
系统应能够对一个访问时间段内可能的并发会话连接数进行限制。需要在web-server配置。
4.6.3 防护缺陷
失效的身份认证和会话管理。
通常,通过错误使用应用程序的身份认证和会话管理功能,攻击者能够破译密码、密钥或会话令牌,或者利用其它开发中的缺陷来冒充其他用户的身份(暂时或永久)。
错误的授权和身份验证(移动客户端)包括对终端用户不安全的身份验证或不安全的会话管理。这包括:
当被要求时,没有对所有用户进行身份识别。
当被要求时,没有保持对用户身份的确认。
会话管理中的漏洞。
4.6.4 实现方案
数字身份
在用户模型userDao中添加一个uuid标识,该UUID可以根据需要再进行拼接,在用户登录后把用户的uuid标识存入session中,在后续的操作中涉及用户权限相关时从session中获取用户uuid进行权限判断。

public String getUUID(){
    UUID uuid=UUID.randomUUID();
    String str = uuid.toString(); 
    String uuidStr=str.replace("-", "");
    return uuidStr;
}
…
String uuidStr = getUUID();
UserDao u = UserDao();
u.Adduser(username,password,uuidStr);
…

身份认证
《应用安全设计规范》描述不同的安全级别应该具备的身份认证条件,不同级别系统中数字身份、身份验证和会话管理控制要求均有不同。
安全级别一级只需要单因素身份验证,通常通过使用密码。安全级别二级需要应用程序具备多因素身份认证的功能。安全级别三级的系统需要基于密钥或其他识别技术的身份认证(比如生物识别)。
会话管理
一旦进行了最初的成功用户身份验证,应用程序可以选择在指定的时间内跟踪和维护这种身份验证状态。在指定时间内将允许用户继续使用应用程序,而无需对每个请求进行重新身份验证。跟踪此用户状态称为会话管理。
在会话中跟踪用户状态。这个会话通常存储在服务器上,用于传统的基于web的会话管理。会话管理会生成一个会话标识符给用户,以便用户能够识别哪个服务器端会话包含正确的用户数据。客户端只需要维护这个会话标识符,会话标识符会将敏感的服务器端会话数据与客户端隔离。
在构建或实现会话管理解决方案时,应充分考虑如下控制点:
确保会话id具有足够的长度、随机性和唯一性。
在身份验证和重新身份验证期后,重新生成一个新的会话id。
实现会话超时机制,为每个会话设置一个最大的有效时间周期,超时后用户必须重新进行身份验证。超时的长度应该与受保护数据的值成反比。
但是,数字身份、身份验证和会话管理是非常重要的主题,这里我们只提出会话管理实现的安全基线,更复杂的业务实现请进行专项安全评估。更多详情可参考Session_Management_Cheat_Shee https://www.owasp.org/index.php/Session_Management_Cheat_Sheet
参考案例
案例1:身份认证
一级–根据密码进行身份认证
1.密码策略
密码至少应符合以下要求:
如果使用多因子认证(MFA)和其他控件,则长度至少为8个字符。如果是非多因子认证,密码长度需要增加到至少10个字符。
所有输入的ASCII字符以及空格字符都应该存在记住的密码中。
鼓励使用长密码和口令句。
复杂性需求可降低,因为这些需求的有效性和安全性有限。相反,建议采用多因子认证(MFA)或更长的密码长度等安全性有效性较高的密码策略。
禁止使用常用或已泄漏的密码。可以选择阻止前1000或10000个最常见的密码,这些密码符合以上长度要求但可以在密码列表中找到,也属于不安全密码。下面的链接包含最常见的密码:https://github.com/danielmiessler/seclists/tree/master/password
2.实现安全密码恢复机制
应用程序通常有一种机制:在用户忘记密码的情况下允许用户找回密码。一个好的密码恢复功能设计工作流应使用多因素身份验证元素。例如,首先问一个安全问题再使用手机验证码认证功能。
有关详细信息,请参阅:Forgot_Password_Cheat_SheetChoosing_and_Using_Security_Questions_Cheat_Sheet
3.实现安全密码存储
为了提供强大的身份验证控制,应用程序必须安全地存储用户凭证。此外,还应该有加密控制,以便如果凭证(例如密码)受到攻击,攻击者不能立即访问该信息。
4.PHP密码存储示例
下面是一个使用password_hash()函数(从5.5.0开始可用)在PHP中进行哈希加密的示例,该函数默认使用bcrypt算法。

<?php
$cost = 15;
$password_hash = password_hash("secret_password", PASSWORD_DEFAULT, ["cost" => $cost] ); 
?>

更多详细信息请参阅OWASP Password Storage Cheat Sheet:
https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet
5.二级–多因素身份认证
安全级别二级标准适用于风险较高的应用程序,需要多因素身份验证。
多因素身份认证通过要求用户使用以下组合来标识自己,从而进行身份认证:
密码或PIN码;
令牌或短信验证码等;
使用密码作为唯一因素安全性较弱。多因素解决方案通过要求攻击者获取多个元素来对服务进行身份验证,提高了攻击成本。
值得注意的是,当生物识别技术作为一个单一的认证因素被使用时,它并不被认为是数字认证的可接受密码。这些信息可以在网上获取,也可以在不知情的情况下,通过手机拍照(例如:面部图像),从别人触摸过的物体(例如:潜在的指纹)中提取,或者通过高分辨率的图像(例如:虹膜图案)获取。生物识别只能作为物理身份验证器的多因素身份验证的一部分使用。
6.三级–基于密钥的身份认证
安全级别三级级标准要求“基于通过加密协议持有密钥的证明”的身份验证。这种类型的身份验证用于实现最高的身份验证保证级别。这通常是通过硬件加密模块完成的,生物识别技术,比如指纹。

案例2:会话管理
浏览器cookie是web应用程序的常见的方法来存储会话标识符为web应用程序实现标准的会话管理技术。这里有一些在使用浏览器cookie时需要考虑的防御措施。
当浏览器cookie被用作跟踪经过身份验证的用户会话的机制时,这些cookie应该可以访问最少的域和路径集,并且应该标记为在会话的有效期之后过期。
应设置“安全”标志,以确保通过仅安全通道(TLS)进行传输。
设置httponly标志以防止通过JavaScript访问cookie。
向cookie添加“samesite”属性可以防止一些现代浏览器发送带有跨站点请求的cookie,并提供对跨站点请求伪造和信息泄漏攻击的保护。
会话令牌
服务器端会话可能会限制某些形式的身份验证。“无状态服务”允许客户端为性能目的管理会话数据,这样服务器就不必为存储和验证用户会话而负担太多。这些“无状态”应用程序生成一个短时间的访问令牌,可用于对客户机请求进行身份验证,而无需在初始身份验证之后发送用户的凭据。
JSON Web Token (JWT)是一个开放标准(RFC 7519),该token被设计的紧凑且安全,可以安全地将各方之间的信息作为JSON对象传输。可以验证和信任这些信息,因为它是数字签名的。JWT令牌是在身份验证期间创建的,并在任何处理之前由服务器进行验证。
但是,在初始创建之后,服务器通常不会保存JWT。JWT通常是服务端创建的,然后交给客户端,服务器只对JWT进行验证而不会以任何方式保存。token的完整性是通过使用数字签名来维护的,因此服务器一定时间内验证JWT仍然有效,并且不会变更。
这种方法既无状态又可移植,因为客户机和服务器技术可以不同,但仍然可以交互。
4.7 实施访问控制
4.7.1 描述说明
访问控制是控制对某个资源的访问,授予或拒绝特定请求的过程。没有它,所有人都可以访问任何资源。有了访问控制,用户在获取实际访问资源或进行操作之前,必须通过识别、验证、授权。应该注意,授权(验证对特定特征或资源的访问)不等同于认证(验证身份)。
访问控制控制着一个主体(subject)可以访问哪些对象(objects),主体是指可以授予或拒绝访问某个对象的人或事物,如用户,程序,系统进程。对象的例子如文件、打印机、程序、系统进程等。
访问控制的模型主要有:

访问控制方式描述
自由访问控制(DAC)自由访问控制(DAC)是基于用户身份(Identity)的访问,DAC中的资源都有一个可以访问它的用户列表(ACL)。主体对它所属的对象拥有全部的控制权。如微软的NTFS。DAC最大缺陷就是对权限控制比较分散,不便于管理,比如无法简单地将一组文件设置统一的权限开放给指定的多个用户。
强制访问控制(MAC)强制访问控制(MAC)解决了DAC权限控制过于分散的问题,由系统管理员管理负责访问控制,且用户不能直接改变强制访问控制属性。策略定义了哪个主体能访问哪个对象。这种访问控制模型可以增加安全级别,因为它基于策略,任何没有被显式授权的操作都不能执行。主要方式为:主体获得权限标记,对象得到分类权限标记,访问权根据主体的数字化标记的访问级别和对象标记的访问级别来授予。
基于角色的访问控制(RBAC)基于角色的访问控制(RBAC)因为DAC和MAC的诸多限制,于是诞生了RBAC,并且成为了迄今为止最为普及的权限设计模型。由管理员定义一系列角色(roles)并把它们赋予主体。设置对象为某个类型,主体具有相应的角色就可以访问它。这样就把管理员从定义每个用户的许可权限的繁冗工作中解放出来。
基于属性的访问控制(ABAC)基于属性的访问控制(ABAC)通过动态计算一个或一组属性来是否满足某种条件来进行授权判断(可以编写简单的逻辑)。属性通常来说分为四类:用户属性(如用户年龄),环境属性(如当前时间),操作属性(如读取)和对象属性(如一篇文章,又称资源属性),所以理论上能够实现非常灵活的权限控制,几乎能满足所有类型的需求。

4.7.2 规范要求
应在安全策略控制范围内,使用户对其创建的客体具有相应的访问操作权限,并能将这些权限部分或全部授予其他用户;
应在安全策略控制范围内,使用户对其创建内容(个人资料、订单、流程)有相应的访问操作权限,并能将这些权限部分或全部授予其他用户。
系统应能够识别非认证的地址访问并拒绝访问,对非认证的地址访问请求提示警告。
系统应对非认证访问的请求进行次数限制,超出次数应进行IP锁定。
有访问控制限制的所有用户和数据属性以及策略信息不能由最终用户操作,除非特别授权。
应存在用于保护对各类型受保护资源访问的集中式机制(包括调用外部授权服务的库)。
应用程序应正确执行上下文相关权限验证,以不允许通过参数篡改进行未经授权的操作。
4.7.3 防护缺陷
失效的访问控制
未对通过身份验证的用户实施恰当的访问控制。攻击者可以利用这些缺陷访问未经授权的功能或数据,例如:访问其他用户的帐户、查看敏感文件、修改其他用户的数据、更改访问权限等。
错误的授权和认证(移动客户端)
攻击者会通过向移动应用程序的后端服务器提交服务请求并绕过与移动应用程序的任何直接交互来伪造或绕过身份验证。此提交过程通常通过设备内的移动恶意软件或攻击者拥有的僵尸网络来完成。
4.7.4 实现方案
在应用程序开发的初始阶段应考虑以下访问控制设计要求:
1.尽早进行访问控制
授权的设计可以由简单开始,之后根据应用系统的需求演进为较为复杂的安全控管。在设计阶段有些安全的设计需要考虑,一旦选定特定的授权控制机制后,之后要再重新更改新的授权机制会比较困难,特别是在多租户的使用环境下,权限管理在应用系统安全防护更是重要。
2.强制所有的存取都需要经过权限控制
有许多的框架或是程序语言只有在程序代码中加入该功能的检查时才会进行权限控制,建议权限控制应该是中央控管,所有的存取都应该要在第一时间做权限验证,考虑可以设计一个自动过滤的机制,将所有的存取都透过权限控制的方式检查。
3.预设不授权
透过自动权限检查的机制,考虑预设将所有没有经过权限检查的存取都不允许存取,这样可以避免新功能因为程序开发遗漏授权检查而导致跳过授权验证的步骤。
4.最小权限原则
当设计访问控制时,所有的用户或是系统组件应该都默认配置最小的权限,在最短的有效权限时间内执行相关的功能。
5.避免角色权限控制
有许多的框架依据使用者角色来决定访问权限,但是程序实际上是以用户与其对应的功能权限来做检查,举例来说,如果编码时根据角色判断,一旦出现角色权限变更的情况就需要修改代码。下面是根据角色判断的范例:

if (user.hasRole("ADMIN")) || (user.hasRole("MANAGER")) {
deleteAccount();
}
正确的根据权限进行的安全编码为:
if (user.hasAccess("DELETE_ACCOUNT")) {
deleteAccount();
}

6.记录所有访问控制事件
应记录所有访问控制失败事件,因为这些事件可能表示攻击者正进行攻击,探测应用程序的漏洞。
7.访问控制验证工具
带有可选的访问控制测试功能的OWASP ZAP:
https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project
https://github.com/zaproxy/zap-extensions/wiki/HelpAddonsAccessControlConcepts
参考案例
案例一:Java 范例
就像上述所讨论,建议将访问控制定义与商业逻辑分开,这样的安全设计方式就可以透过中央安全规则管理实现弹性化权限配置。举例来说 Apache Shiro API 提供简单的 INI-based configuration file 安全配置档案让权限控制规则可以透过模块的方式弹性调整。Apache Shiro 也可以与许多其它 Java 兼容的框架运作 (Spring,Guice,JBoss,etc)。Aspects 也提供可以把权限控制与应用程序代码分离的机制,并且提供可以稽核的实作方式。
4.8 数据保护
4.8.1 描述说明
密码、信用卡号、健康记录、个人信息和商业机密等敏感数据都需要保护,特别是GDPR、PCI DSS等法律法规保护的敏感数据。攻击者可以通过多种方式从Web和Web服务应用程序中窃取数据。例如,如果通过互联网发送的敏感信息没有进行通信加密,攻击者可通过共享无线连接查看并窃取其他用户的数据。此外,攻击者可以使用SQL注入等漏洞从应用程序数据库中窃取密码和其他数据。
4.8.2 规范要求
应采用密码机制支持的完整性校验机制或其他具有相应安全强度的完整性校验机制,以防止非授权情况下的非法修改;利用密码算法来保证数据的完整性,如利用HASH函数计算通信数据的散列值,并用非对称加密算法对散列值进行加解密;
应对存储和处理的用户数据的完整性进行校验,以发现其完整性是否被破坏;
采用密码技术支持保密性保护机制或其他具有相应安全强度的手段提供保密性保护;
在数据完整性受到破坏时能对重要数据进行恢复;
应设置独立服务器,用于存放用户上传文件;
应对用户上传的文件,进行重新命名,保证不容易被猜测;
应对用户上传文件内容进行检查,禁止非法文件上传;
系统接受用户数据输入时,应对客户信息在客户端进行格式和类型的检测;
系统接受用户数据输入时,应对关键客户信息在服务器端再次进行格式和类型的检测;
系统输出用户数据到用户客户端时,对输出数据进行转义;
系统中应采用密码技术支持的保密性保护机制或其他具有相应安全强度的手段提供保密性保护;
系统中不得使用已经被证明为不安全的算法或者自定义不安全算法进行用户数据加密;
系统中涉及的用户功能页面,不应使用用户ID等易猜测的明文作为页面的URL信息;
应保证用户鉴别信息所在的存储空间被释放或再分配给其他用户前得到完全清除,无论这些信息是存放在硬盘上还是在内存中;应保证系统内的文件、目录和数据库记录等资源所在的存储空间被释放或重新分配给其他用户前得到完全清除;
系统中涉及金额限制的地方应该做明确的界定,并保证相关交易数据不会超过界定值;
应避免客户端浏览器启用缓存用户名、密码等账户信息;
保护重要秘密信息免受未授权访问,包括但不仅限于:
1)用户敏感信息(比如:姓名、密码、手机号、银行卡号、身份证号),在页面显示及传输过程中应注意遮盖及加密;
2)应用程序配置信息(比如:配置文件中的用户名及密码),应加密后再进行存储;
3)数据库中存储的用户密码等鉴别信息,应使用安全Hash算法(比如:国密SM3),并进行加盐(Salted)处理,然后将盐和密码哈希值一起保存在数据库中,或通过加密机完成加密。
重要参数(比如:用户密码)应使用HTTP POST方式提交;禁止使用HTTP GET方式,避免被记录到Web访问日志中;
确保应用程序代码中无硬编码的密码;密码在存储和传输过程中必须以密文方式存在;密码输入时禁止明文回显,在用户端显示时须进行遮盖处理。
4.8.3 防护缺陷
敏感数据泄露
许多Web应用程序和API都无法正确保护敏感数据,例如:财务数据、医疗数据和PII数据。攻击者可以通过窃取或修改未加密的数据来实施信用卡诈骗、身份盗窃或其他犯罪行为。未加密的敏感数据容易受到破坏,因此,我们需要对敏感数据加密,这些数据包括:传输过程中的数据、存储的数据以及浏览器的交互数据。
不安全的数据存储(移动客户端)
移动客户端文件系统很容易访问。对移动设备进行root或越狱可以绕过任何加密保护。如果数据未得到正确保护,可直接使用专用工具即可查看应用程序数据。
4.8.4 实现方案
数据定级:
对系统中的数据进行分类并确定每个数据的敏感级别。 然后,将确定不同敏感级别的保护措施。例如,将不敏感的公共营销信息分类为可以放置在公共网站上的公共数据;信用卡号可以被分类为私人用户数据,其可能需要在存储或传输时被加密。
加密传输过程中的数据:
当传输敏感数据的时候, 系统的每一个环节或是网络都应该在传递的过程中加密。TLS 是目前最普遍被网站使用来做数据传递加密的方式,尽管已经有些已知的风险被发现(e.g. Heartbleed),还是建议在传递的过程中使用TLS 的加密方式。
数据加密存储
密码的储存很难做到安全,数据的分类也会影响数据加密的方式,例如信用卡数据就必须符合 PCI-DSS 认证标准。如果你希望要自己建立自己的密码系统, 也必须确定有足够的专业判断该密码的强度,实务上建议使用业界已经经过验证的加密算法, 而非自行开发加密算法。可以使用Google Tink项目,Libsodium以及内置于许多软件框架和云服务中的安全存储功能。
安全实现及验证工具
SSLyze:https://github.com/nabla-c0d3/sslyze
SSLLabs:https://www.ssllabs.com/ssltest/
OWASP O-Saft TLS Tool:https://www.owasp.org/index.php/O-Saft
GitRob:https://github.com/michenriksen/gitrob
TruffleHog:https://github.com/dxa4481/truffleHog
KeyWhiz:https://github.com/square/keywhiz
Hashicorp Vault:https://www.vaultproject.io/
Amazon KMS:https://aws.amazon.com/cn/kms/
参考案例
案例一:手机应用程序客户端的储存安全防护
对于手机装置来说, 因为经常会有遗失或是被窃取的问题, 因为防护手机端的数据安全需要适当的防护措施。应用程序如果建置不当, 很容易导致严重的信息外泄(举例来书:认证信息, 存取验证 token 等)。当管理重要敏感数据时最好的方式就是不要将数据储存在手机端, 甚至透过 iOS keychain 的方式储存都不要。
案例二:密钥管理
密钥使用于应用程序敏感功能的数据。例如,密钥可用于签署JWT、保护信用卡、提供各种形式的身份验证以及促进其他敏感的安全功能。 在管理密钥时,应遵循一些规则,包括:
确保所有密钥免受未经授权的访问;
将密钥存储在适当的密钥保险库中。
案例三:应用密钥管理
应用程序包含很多敏感数据,包括证书、SQL连接密码、第三方服务帐户凭据、密码、SSH密钥、加密密钥等。未经授权披露或修改这些秘密可能导致系统权限被获取。
在管理应用程序敏感数据时,请考虑以下事项:
1)不要在代码、配置文件中存储敏感数据或通过环境变量传递它们。(使用GitRob或TruffleHog等工具扫描代码存储库以查看是否存在敏感数据信息。)
2)将密钥等数据保存在KeyWhiz或Hashicorp的Vault项目或Amazon KMS等秘密保险库中,以便在运行时实现敏感数据安全存储和应用敏感数据安全访问。
4.9 建立日志审计与入侵检测
4.9.1 描述说明
日志记录已经被大多数开发人员用于调试和诊断。同样安全日志记录也是应用程序运行时操作记录的安全信息。入侵检测是使用各种形式的自动化对应用程序和安全日志进行实时审查。
安全日志审计的优点:
1)提供入侵检测分析依据
2)用于事后分析调查
3)满足合规性要求
4.9.2 规范要求
高质量日志通常会包含敏感数据,必须按照当地法律法规进行保护。应该包含以下内容:
1)如果非必要,不要收集或记录敏感信息;
2)确保所有日志信息都按它的数据等级被安全的处理和保护;
3)确保日志不是永久存储,而是有一个尽可能短的绝对生命周期。
可使用哈希算法以确保日志记录完整性;
开发测试过程中应采取必要的监控措施,如运行日志、网络监控记录的日常维护和报警信息分析和处理工作;
确保审计记录不被破坏或非授权访问以及防止审计记录丢失等:
1)应将应用系统审计记录以数据表形式存放至数据库中,并建立访问控制和定期备份机制,确保审计记录不被破坏或非授权访问以及防止审计记录丢失等。
能对特定安全事件进行报警,终止违例进程等:
1)应保证无法单独中断审计进程,无法删除、修改或覆盖审计记录;
2)所有不可打印的符号和字段分隔符应在日志中正确编码,以防止日志注入;
3)日志应存储在与日志产生的应用运行在不同的磁盘分区上。
4.9.3 实现方案
安全日志记录实现最佳实践:
1)遵循系统内和组织系统内的通用日志记录格式和方法。常见日志记录框架的一个示例是Apache Logging Services,它有助于在Java、PHP、.NET和C ++应用程序之间提供日志记录一致性;
2)不要记录太多或太少。例如,请确保始终记录时间戳和标识信息,包括源IP和用户ID,但请注意不要记录私人或机密数据;
3)密切关注跨节点的时间同步,以确保时间戳保持一致。
入侵检测和响应的记录,使用日志记录来标识指示用户恶意行为的活动。记录的潜在恶意活动,包括但不限于:
1)提交的数据超出预期的数值范围;
2)提交的数据涉及对不应修改的数据的更改(选择列表,复选框或其他有限的条目组件);
3)违反服务器端访问控制规则的请求等;
4)当应用程序遇到此类活动时,应用程序应至少记录该活动并将其标记为高严重性问题。理想情况下,您的应用程序还应响应可能的已识别攻击,例如使用户的会话无效并锁定用户的帐户。响应机制允许软件实时响应可能的已识别攻击。
安全的日志记录设计必须以安全的方式构建和管理日志记录解决方案。安全的日志记录设计可能包括以下内容:
1)在记录之前编码并验证任何危险字符,以防止日志注入或日志记录攻击;
2)不要记录敏感信息。例如:密码、会话ID、信用卡或社会保险号;
3)保护日志完整性。攻击者可能会试图篡改日志。因此,应考虑日志文件和日志更改审核的权限;
4)将日志从分布式系统转发到中央安全日志记录服务。如果一个节点受到威胁,这将确保日志数据不会丢失。另外也有助于集中监控。
安全实现和验证工具
1)OWASP安全日志项目:https://www.owasp.org/index.php/Reviewing_Code_for_Logging_Issues
2)Apache日志记录服务:https://logging.apache.org/
4.10 处理所有错误与例外
4.10.1 描述说明
设计错误与例外处理是一个琐碎的过程,但是错误与例外状况的处理却是编码防护重要的一环,不恰当的错误处理会导致许多安全漏洞的风险:
信息泄露:
错误消息中可能会泄漏敏感信息,黑客通过此漏洞可知道服务器平台所使用的技术与设计。举例来说,回复 stack trace 或是其它内部详细错误的讯息都会导致让黑客知道更多后端服务器的运作逻辑。黑客也会透过不同的错误型态(例如,错误的用户或是错误的密码等)来了解服务器检查的机制。
TLS绕过:
苹果的GoToFail漏洞是执行了代码中的错误控制流,导致苹果系统上TLS连接的完全泄露。
DOS:
缺少基本错误处理可能导致系统关闭,这是攻击者相当容易利用的一个漏洞;大量错误处理问题可能导致CPU或磁盘使用量增加,从而导致系统性能下降。
4.10.2 规范要求
当异常发生时,不要将系统产生的异常信息(比如:调试或堆栈信息)直接反馈给用户;应创建默认的错误页面,使用通用的错误消息,防止攻击者从出错页面中得到系统信息。
安全控制中的错误处理逻辑默认情况下拒绝访问。
4.10.3 实现方案
为充分满足错误与异常处理要求,应保证:
以集中方式管理异常,以避免代码中出现重复的try / catch块。 确保在应用程序内正确处理所有意外行为。
对于捕获的异常要进行相应的处理,不能忽略已捕获的异常。
确保向用户显示的错误消息不会泄漏敏感信息,但仍然足够冗长以启用正确的用户响应。
确保能够给运维、QA、取证或事件响应的团队提供足够的日志信息,以便了解问题。仔细测试并验证错误处理代码。
安全实现和验证工具
Error Prone:
来自Google的静态分析工具,用于捕获Java开发人员错误处理中的常见错误,参考地址:http://errorprone.info/
Chaos Monkey:
Netflix的Chaos Monkey是用于在运行时查找错误的最著名的自动化工具之一,它故意禁用系统实例以确保整体服务能够正确恢复。参考地址:https://github.com/Netflix/SimianArmy
4.10.4 参考案例
案例一
不允许暴露异常的敏感信息,没有过滤敏感信息的异常堆栈往往会导致信息泄漏
不正确的写法:

try {
FileInputStream fis =
new FileInputStream(System.getenv("APPDATA") + args[0]);
} catch (FileNotFoundException e) {
// Log the exception
throw new IOException("Unable to retrieve file", e);
}

正确的写法:

class ExceptionExample {
public static void main(String[] args) {
File file = null;
try {
file = new File(System.getenv("APPDATA") +
args[0]).getCanonicalFile();
if (!file.getPath().startsWith("c:\\homepath")) {
log.error("Invalid file");
return;
}
} catch (IOException x) {
log.error("Invalid file");
return;
}
try {
FileInputStream fis = new FileInputStream(file);
} catch (FileNotFoundException x) {
log.error("Invalid file");
return;
}

  1. a-zA-Z ↩︎

  2. a-zA-Z ↩︎

  3. a-z0-9_ ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
网络安全漏洞标识与描述规范,是一个针对网站、服务器、应用程序等进行漏洞标识与描述的指南,旨在统一网络安全行业的术语与描述,提高漏洞识别与修复的效率。 该规范的主要内容包括以下几个方面: 1. 漏洞编码规范:给每个漏洞分配一个唯一的标识码,便于快速识别和查找漏洞。标识码一般由数字和字母组成,具备一定的逻辑顺序,便于分类与管理。 2. 漏洞描述规范:对漏洞进行详细的描述,包括漏洞的原理、影响范围、攻击难度、修复建议等信息,以便安全专家和开发人员更好地理解和处理漏洞。 3. 漏洞等级划分:根据漏洞的严重程度和危害等级,将漏洞划分为不同的等级,例如:低、中、高、紧急等级。这有助于优先处理高危漏洞,减少对系统的影响。 4. 漏洞报告模板:规定了漏洞报告应包含的必要信息,如漏洞名称、漏洞编号、漏洞描述、漏洞修复方案等,以便于信息的传递和处理。 5. 漏洞修复验证标准:定义了漏洞修复完成后的验证标准,确保漏洞修复工作有效实施,并对修复后的系统进行一定的验证和测试。 通过遵守网络安全漏洞标识与描述规范,我们可以更好地提高漏洞的识别和分析能力,加强漏洞的修复与管理工作,从而提升我们的网络安全防护水平。同时,规范的使用也方便了安全专家之间的沟通和交流,共同促进整个网络安全行业的发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫慌搞安全

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值