OWASP安全编码规范详情
0x00 原则 概览
开发安全的软件需要对安全原则有基本的了解。虽然对于安全原则的全面评估超出了本指南的范围,但是我们还是提供了一个快速的概览。软件安全的目标是要维护信息资源的 保密性 , 完整性 ,和 可用性 ,以确保业务的成功运作。该目标通过实施 安全控制 来实现。本指南重点介绍具体的技术控制,以 缓解 常见软件 漏洞 的发生。虽然主要的关注点是 Web应用程序及其配套的基础设施,但是本指南的大部分内容可应用于任意软件部署平台。为了保护业务免受来自与软件相关的不能接受的风险,了解风险的意义是很有帮助的。风险是一组威胁业务成功因素的集合。它可以被定义为:一个 威胁代理 与一个可能含有 漏洞 的 系统 交互,该漏洞可被 利用 并造成 影响 。虽然这可能看起来象是一个抽象的概念,但可以这样想象它:一个汽车盗窃犯(威胁代理)来到一个停车场(系统)寻没有锁车门(漏洞)的车,当到一个时,他们打开门(利用)并拿走里面任何的东西(影响)。所有这些因素在安全软件开发时都扮演了一个角。开发团队采用的方法和攻击者攻击应用程序所采用的方法之间有一个根本区别。开发团队通常采用的方法是基于应用程序的目的行为。换句话说,开发团队根据功能需求
文档和用例设计一个应用程序以执行特定的任务。而另一方面,攻击者,基于“没有具体说明应拒绝的行为,则被认为是可行的”原则,对于应用程序可以做什么更感兴趣。为了解决这个问题,一些额外的元素需要被集成到软件生命周期的早期阶段。这些新元素是 安全需求 和 滥用实例 。本指南旨在帮助明确高等级的安全需求,并解决许多常见的滥用情况。Web开发团队应当明白,基于客户端的输入验证、隐藏字段和界面控件(例如,下拉键和单选按钮)的客户端控制,所带来的安全性收益是有限的,这一点非常重要。攻击者可以使用工具,比如:客户端的 Web代理(例如,OWASP WebScarab,Burp)或网络数据包捕获工具(例如,Wireshark),进行应用程序流量分析,提交定制的请求,并绕过所有的接口。另外,Flash,JavaApplet 和其它客户端对象可以被反编译并进行漏洞分析。软件的安全漏洞可以在软件开发生命周期的任何阶段被引入,包括:
最初没有明确的安全需求;
创建有逻辑错误的概念设计;
使用糟糕的编码规范,从而带来了技术漏洞;
软件部署不当;
在维护或者更新过程中引入缺陷。
最初没有明确的安全需求;
创建有逻辑错误的概念设计;
使用糟糕的编码规范,从而带来了技术漏洞;
软件部署不当;
在维护或者更新过程中引入缺陷。
此外,还有重要的一点需要明白,软件漏洞可以超出软件本身的范围。根据不同的软件、漏洞和配套基础设施的性质,一次成功的攻击会影响下面任何或者所有的方面:
软件和其相关的信息;
相关服务器的操作系统;
后端数据库;
在共享环境中的其它应用程序;
用户的系统;
与用户交互的其它软件。
软件和其相关的信息;
相关服务器的操作系统;
后端数据库;
在共享环境中的其它应用程序;
用户的系统;
与用户交互的其它软件。
0x01 输入验证
在可信系统(比如:服务器)上执行所有的数据验证。
识别所有的数据源,并将其分为可信的和不可信的。验证所有来自不可信数据源(比如:数据库,文件流,等)的数据。
应当为应用程序应提供一个集中的输入验证规则。
为所有输入明确恰当的字符集,比如:UTF-8。
识别所有的数据源,并将其分为可信的和不可信的。验证所有来自不可信数据源(比如:数据库,文件流,等)的数据。
应当为应用程序应提供一个集中的输入验证规则。
为所有输入明确恰当的字符集,比如:UTF-8。
在输入验证前,将数据按照常用字符进行编码( 规范化 )。
丢弃任何没有通过输入验证的数据。
确定系统是否支持 UTF-8扩展字符集,如果支持,在 UTF-8解码完成以后进行输入验证。
在处理以前,验证所有来自客户端的数据,包括:所有参数、URL、HTTP头信息(比如:cookie名字和数据值)。确定包括了来自 JavaScript、Flash或其他嵌入代码的 post back信息。
验证在请求和响应的报头信息中只含有 ASCII字符。
核实来自重定向输入的数据(一个攻击者可能向重定向的目标直接提交恶意代码,从而避开应用程序逻辑以及在重定向前执行的任何验证)。
验证正确的数据类型。
验证数据范围。
验证数据长度。
尽可能采用“白名单”形式,验证所有的输入。
如果任何潜在的 危险字符 必须被作为输入,请确保您执行了额外的控制,比如:输出编码、特定的安全 API、以及在应用程序中使用的原因。部分常见的危险字符包括:< > " ' % ( )
丢弃任何没有通过输入验证的数据。
确定系统是否支持 UTF-8扩展字符集,如果支持,在 UTF-8解码完成以后进行输入验证。
在处理以前,验证所有来自客户端的数据,包括:所有参数、URL、HTTP头信息(比如:cookie名字和数据值)。确定包括了来自 JavaScript、Flash或其他嵌入代码的 post back信息。
验证在请求和响应的报头信息中只含有 ASCII字符。
核实来自重定向输入的数据(一个攻击者可能向重定向的目标直接提交恶意代码,从而避开应用程序逻辑以及在重定向前执行的任何验证)。
验证正确的数据类型。
验证数据范围。
验证数据长度。
尽可能采用“白名单”形式,验证所有的输入。
如果任何潜在的 危险字符 必须被作为输入,请确保您执行了额外的控制,比如:输出编码、特定的安全 API、以及在应用程序中使用的原因。部分常见的危险字符包括:< > " ' % ( )
& + \ \' \" 。
如果您使用的标准验证规则无法验证下面的输入,那么它们需要被单独验证:
o 验证空字节 (%00);
o 验证换行符 (%0d, %0a, \r, \n);
o 验证路径替代字符“点-点-斜杠”(../或 ..\)。如果支持 UTF-8扩展字符集编码,验证替代字符: %c0%ae%c0%ae/ (使用 规范化 验证双编码或其他类型的编码攻击)。
如果您使用的标准验证规则无法验证下面的输入,那么它们需要被单独验证:
o 验证空字节 (%00);
o 验证换行符 (%0d, %0a, \r, \n);
o 验证路径替代字符“点-点-斜杠”(../或 ..\)。如果支持 UTF-8扩展字符集编码,验证替代字符: %c0%ae%c0%ae/ (使用 规范化 验证双编码或其他类型的编码攻击)。
0x02 输出编码
在可信系统(比如:服务器)上执行所有的编码。
为每一种输出编码方法采用一个标准的、已通过测试的规则。
通过语义输出编码方式,对所有返回到客户端的来自于应用程序信任边界之外的数据进行编码。HTML实体编码是一个例子,但不是在所有的情况下都可用。
除非对目标编译器是安全的,否则请对所有字符进行编码。
针对 SQL、XML和 LDAP查询,语义净化所有不可信数据的输出。
对于操作系统命令,净化所有不可信数据输出。
为每一种输出编码方法采用一个标准的、已通过测试的规则。
通过语义输出编码方式,对所有返回到客户端的来自于应用程序信任边界之外的数据进行编码。HTML实体编码是一个例子,但不是在所有的情况下都可用。
除非对目标编译器是安全的,否则请对所有字符进行编码。
针对 SQL、XML和 LDAP查询,语义净化所有不可信数据的输出。
对于操作系统命令,净化所有不可信数据输出。
0x03 身份验证和密码管理
除了那些特定设为“公开”的内容以外,对所有的网页和资源要求身份验证。
所有的身份验证过程必须在可信系统(比如:服务器)上执行。
在任何可能的情况下,建立并使用标准的、已通过测试的身份验证服务。
为所有身份验证控制使用一个集中实现的方法,其中包括利用库文件请求外部身份验证服务。
将身份验证逻辑从被请求的资源中隔离开,并使用重定向到或来自集中的身份验证控制。
所有的身份验证控制应当安全的处理未成功的身份验证。
所有的管理和账户管理功能至少应当具有和主要身份验证机制一样的安全性。
如果您的应用程序管理着凭证的存储,那么应当保证只保存了通过使用强加密单向 salted哈希算法得到的密码,并且只有应用程序具有对保存密码和密钥的表/文件的写权限(如果可以避免的话,不要使用 MD5算法)。
密码哈希必须在可信系统(比如:服务器)上执行。
只有当所有的数据输入以后,才进行身份验证数据的验证,特别是对连续身份验证机制。
身份验证的失败提示信息应当避免过于明确。比如:可以使用“用户名和/或密码错误”,而
所有的身份验证过程必须在可信系统(比如:服务器)上执行。
在任何可能的情况下,建立并使用标准的、已通过测试的身份验证服务。
为所有身份验证控制使用一个集中实现的方法,其中包括利用库文件请求外部身份验证服务。
将身份验证逻辑从被请求的资源中隔离开,并使用重定向到或来自集中的身份验证控制。
所有的身份验证控制应当安全的处理未成功的身份验证。
所有的管理和账户管理功能至少应当具有和主要身份验证机制一样的安全性。
如果您的应用程序管理着凭证的存储,那么应当保证只保存了通过使用强加密单向 salted哈希算法得到的密码,并且只有应用程序具有对保存密码和密钥的表/文件的写权限(如果可以避免的话,不要使用 MD5算法)。
密码哈希必须在可信系统(比如:服务器)上执行。
只有当所有的数据输入以后,才进行身份验证数据的验证,特别是对连续身份验证机制。
身份验证的失败提示信息应当避免过于明确。比如:可以使用“用户名和/或密码错误”,而
不要使用“用户名错误”或者“密码错误”。错误提示信息在显示和源代码中应保持一致。
为涉及敏感信息或功能的外部系统连接使用身份验证。
用于访问应用程序以外服务的身份验证凭据信息应当加密,并存储在一个可信系统(比如:服务器)中受到保护的地方。源代码不是一个安全的地方。
只使用 HTTP Post 请求传输身份验证的凭据信息。
非临时密码只在加密连接中发送或作为加密的数据(比如,一封加密的邮件)。通过邮件重设临时密码可以是一个例外。
通过政策或规则加强密码复杂度的要求(比如:要求使用字母、数字和/或特殊符号)。身份验证的凭据信息应当足够复杂以对抗在其所部署环境中的各种威胁攻击。
通过政策和规则加强密码长度要求。常用的是 8个字符长度,但是 16个字符长度更好,或者考虑使用多单词密码短语。
输入的密码应当在用户的屏幕上模糊显示(比如:在 Web表单中使用“password”输入类型)。
当连续多次登录失败后(比如:通常情况下是 5次),应强制锁定账户。账户锁定的时间必须足够长,以阻止暴力攻击猜测登录信息,但是不能长到允许执行一次拒绝服务攻击。
为涉及敏感信息或功能的外部系统连接使用身份验证。
用于访问应用程序以外服务的身份验证凭据信息应当加密,并存储在一个可信系统(比如:服务器)中受到保护的地方。源代码不是一个安全的地方。
只使用 HTTP Post 请求传输身份验证的凭据信息。
非临时密码只在加密连接中发送或作为加密的数据(比如,一封加密的邮件)。通过邮件重设临时密码可以是一个例外。
通过政策或规则加强密码复杂度的要求(比如:要求使用字母、数字和/或特殊符号)。身份验证的凭据信息应当足够复杂以对抗在其所部署环境中的各种威胁攻击。
通过政策和规则加强密码长度要求。常用的是 8个字符长度,但是 16个字符长度更好,或者考虑使用多单词密码短语。
输入的密码应当在用户的屏幕上模糊显示(比如:在 Web表单中使用“password”输入类型)。
当连续多次登录失败后(比如:通常情况下是 5次),应强制锁定账户。账户锁定的时间必须足够长,以阻止暴力攻击猜测登录信息,但是不能长到允许执行一次拒绝服务攻击。
密码重设和更改操作需要类似于账户创建和身份验证的同样控制等级。
密码重设问题应当支持尽可能随机的提问(比如:“最喜爱的书”是一个坏的问题,因为《圣经》是最常见的答案)。
如果使用基于邮件的重设,只将临时链接或密码发送到预先注册的邮件地址。
临时密码和链接应当有一个短暂的有效期。
当再次使用临时密码时,强制修改临时密码。
当密码重新设置时,通知用户。
阻止密码重复使用。
密码在被更改前应当至少使用了一天,以阻止密码重用攻击。
根据政策或规则的要求,强制定期更改密码。关键系统可能会要求更频繁的更改。更改时间周期必须进行明确。
为密码填写框禁用“记住密码”功能。
用户账号的上一次使用信息(成功或失败)应当在下一次成功登录时向用户报告。
执行监控以确定针对使用相同密码的多用户帐户攻击。当用户 ID可以被得到或被猜到时,该攻击模式用来绕开标准的锁死功能。
密码重设问题应当支持尽可能随机的提问(比如:“最喜爱的书”是一个坏的问题,因为《圣经》是最常见的答案)。
如果使用基于邮件的重设,只将临时链接或密码发送到预先注册的邮件地址。
临时密码和链接应当有一个短暂的有效期。
当再次使用临时密码时,强制修改临时密码。
当密码重新设置时,通知用户。
阻止密码重复使用。
密码在被更改前应当至少使用了一天,以阻止密码重用攻击。
根据政策或规则的要求,强制定期更改密码。关键系统可能会要求更频繁的更改。更改时间周期必须进行明确。
为密码填写框禁用“记住密码”功能。
用户账号的上一次使用信息(成功或失败)应当在下一次成功登录时向用户报告。
执行监控以确定针对使用相同密码的多用户帐户攻击。当用户 ID可以被得到或被猜到时,该攻击模式用来绕开标准的锁死功能。
更改所有厂商提供的默认用户 ID和密码,或者禁用相关帐号。
在执行关键操作以前,对用户再次进行身份验证。
为高度敏感或重要的交易账户使用多因子身份验证机制。
如果使用了第三方身份验证的代码,仔细检查代码以保证其不会受到任何恶意代码的影响。
在执行关键操作以前,对用户再次进行身份验证。
为高度敏感或重要的交易账户使用多因子身份验证机制。
如果使用了第三方身份验证的代码,仔细检查代码以保证其不会受到任何恶意代码的影响。
0x04 会话管理
使用服务器或者框架的会话管理控制。应用程序应当只识别有效的会话标识符。
会话标识符必须总是在一个可信系统(比如:服务器)上创建。
会话管理控制应当使用通过审查的算法以保证足够的随机会话标识符。
为包含已验证的会话标识符的 cookie设置域和路径,以为站点设置一个恰当的限制值。
注销功能应当完全终止相关的会话或连接。
注销功能应当可用于所有受身份验证保护的网页。
在平衡的风险和业务功能需求的基础上,设置一个尽量短的会话超时时间。通常情况下,应当不超过几个小时。
会话标识符必须总是在一个可信系统(比如:服务器)上创建。
会话管理控制应当使用通过审查的算法以保证足够的随机会话标识符。
为包含已验证的会话标识符的 cookie设置域和路径,以为站点设置一个恰当的限制值。
注销功能应当完全终止相关的会话或连接。
注销功能应当可用于所有受身份验证保护的网页。
在平衡的风险和业务功能需求的基础上,设置一个尽量短的会话超时时间。通常情况下,应当不超过几个小时。
禁止连续的登录并强制执行周期性的会话终止,即使是活动的会话。特别是对于支持富网络连接或连接到关键系统的应用程序。终止时机应当可以根据业务需求调整,并且用户应当收到足够的通知已减少带来的负面影响。
如果一个会话在登录以前就建立,在成功登录以后,关闭该会话并创建一个新的会话。
在任何重新身份验证过程中建立一个新的会话标识符。
不允许同一用户 ID的并发登录。
不要在 URL、错误信息或日志中暴露会话标识符。会话标识符应当只出现在 HTTP cookie头信息中。比如,不要将会话标识符以 GET 参数进行传递。
通过在服务器上使用恰当的访问控制,保护服务器端会话数据免受来自服务器其他用户的未授权访问。
生成一个新的会话标识符并周期性地使旧会话标识符失效(这可以缓解那些原标识符被获得的特定会话劫持情况)。
在身份验证的时候,如果连接从 HTTP变为 HTTPS,则生成一个新的会话标识符。在应用程序中,推荐持续使用 HTTPS,而非在 HTTP和 HTTPS之间转换。
为服务器端的操作执行标准的会话管理,比如,通过在每个会话中使用强随机令牌或参数
如果一个会话在登录以前就建立,在成功登录以后,关闭该会话并创建一个新的会话。
在任何重新身份验证过程中建立一个新的会话标识符。
不允许同一用户 ID的并发登录。
不要在 URL、错误信息或日志中暴露会话标识符。会话标识符应当只出现在 HTTP cookie头信息中。比如,不要将会话标识符以 GET 参数进行传递。
通过在服务器上使用恰当的访问控制,保护服务器端会话数据免受来自服务器其他用户的未授权访问。
生成一个新的会话标识符并周期性地使旧会话标识符失效(这可以缓解那些原标识符被获得的特定会话劫持情况)。
在身份验证的时候,如果连接从 HTTP变为 HTTPS,则生成一个新的会话标识符。在应用程序中,推荐持续使用 HTTPS,而非在 HTTP和 HTTPS之间转换。
为服务器端的操作执行标准的会话管理,比如,通过在每个会话中使用强随机令牌或参数
来管理账户。该方法可以用来防止跨站点请求伪造攻击。
通过在每个请求或每个会话中使用强随机令牌或参数,为高度敏感或关键的操作提供标准的会话管理。
为在 TLS连接上传输的 cookie设置“安全”属性。
将 cookie设置为 HttpOnly属性,除非在应用程序中明确要求了客户端脚本程序读取或者设置cookie的值。
通过在每个请求或每个会话中使用强随机令牌或参数,为高度敏感或关键的操作提供标准的会话管理。
为在 TLS连接上传输的 cookie设置“安全”属性。
将 cookie设置为 HttpOnly属性,除非在应用程序中明确要求了客户端脚本程序读取或者设置cookie的值。
0x05 访问控制
只使用可信系统对象(比如:服务器端会话对象)以做出访问授权的决定。
使用一个单独的全站点部件以检查访问授权。这包括调用外部授权服务的库文件。
安全的处理访问控制失败的操作。
如果应用程序无法访问其安全配置信息,则拒绝所有的访问。
在每个请求中加强授权控制,包括:服务器端脚本产生的请求,“includes”和来自象 AJAX 和FLASH那样的富客户端技术的请求。
将有特权的逻辑从其他应用程序代码中隔离开。
使用一个单独的全站点部件以检查访问授权。这包括调用外部授权服务的库文件。
安全的处理访问控制失败的操作。
如果应用程序无法访问其安全配置信息,则拒绝所有的访问。
在每个请求中加强授权控制,包括:服务器端脚本产生的请求,“includes”和来自象 AJAX 和FLASH那样的富客户端技术的请求。
将有特权的逻辑从其他应用程序代码中隔离开。
限制只有授权的用户才能访问文件或其他资源,包括那些应用程序外部的直接控制。
限制只有授权的用户才能访问受保护的 URL。
限制只有授权的用户才能访问受保护的功能。
限制只有授权的用户才能访问直接对象引用。
限制只有授权的用户才能访问服务。
限制只有授权的用户才能访问应用程序数据。
限制通过使用访问控制来访问用户、数据属性和策略信息。
cookie阻止好还是不阻止好 限制只有授权的用户才能访问与安全相关的配置信息。
服务器端执行的访问控制规则和表示层实施的访问控制规则必须匹配。
如果状态数据必须存储在客户端,使用加密算法,并在服务器端检查完整性以捕获状态的改变。
强制应用程序逻辑流程遵照业务规则。
限制单一用户或设备在一段时间内可以执行的事务数量。事务数量/时间应当高于实际的业务需求,但也应该足够低以判定自动化攻击。
仅使用“referer”头作为补偿性质的检查,它永远不能被单独用来进行身份验证检查,因为它
限制只有授权的用户才能访问受保护的 URL。
限制只有授权的用户才能访问受保护的功能。
限制只有授权的用户才能访问直接对象引用。
限制只有授权的用户才能访问服务。
限制只有授权的用户才能访问应用程序数据。
限制通过使用访问控制来访问用户、数据属性和策略信息。
cookie阻止好还是不阻止好 限制只有授权的用户才能访问与安全相关的配置信息。
服务器端执行的访问控制规则和表示层实施的访问控制规则必须匹配。
如果状态数据必须存储在客户端,使用加密算法,并在服务器端检查完整性以捕获状态的改变。
强制应用程序逻辑流程遵照业务规则。
限制单一用户或设备在一段时间内可以执行的事务数量。事务数量/时间应当高于实际的业务需求,但也应该足够低以判定自动化攻击。
仅使用“referer”头作为补偿性质的检查,它永远不能被单独用来进行身份验证检查,因为它
可以被伪造。
如果长的身份验证会话被允许,周期性的重新验证用户的身份,以确保他们的权限没有改变。如果发生改变,注销该用户,并强制他们重新执行身份验证。
执行帐户审计并将没有使用的帐号强制失效(比如:在用户密码过期后的 30天以内)。
应用程序必须支持帐户失效,并在帐户停止使用时终止会话(比如:角、职务状况、业务处理的改变,等等)。
服务帐户,或连接到或来自外部系统的帐号,应当只有尽可能小的权限。
建立一个“访问控制政策”以明确一个应用程序的业务规则、数据类型和身份验证的标准或处理流程,确保访问可以被恰当的提供和控制。这包括了为数据和系统资源确定访问需求。
如果长的身份验证会话被允许,周期性的重新验证用户的身份,以确保他们的权限没有改变。如果发生改变,注销该用户,并强制他们重新执行身份验证。
执行帐户审计并将没有使用的帐号强制失效(比如:在用户密码过期后的 30天以内)。
应用程序必须支持帐户失效,并在帐户停止使用时终止会话(比如:角、职务状况、业务处理的改变,等等)。
服务帐户,或连接到或来自外部系统的帐号,应当只有尽可能小的权限。
建立一个“访问控制政策”以明确一个应用程序的业务规则、数据类型和身份验证的标准或处理流程,确保访问可以被恰当的提供和控制。这包括了为数据和系统资源确定访问需求。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论