例如,仅仅依靠防火墙来为仅供内部使用的应用程序提供安全性是一个糟糕的想法,因为有决心和熟练的攻击者可以绕过防火墙。应该增加其他安全机制,以补充防火墙提供的保护(入侵检测设备,对人员的安全意识培训,等等),以应对不同的攻击载体,包括人为因素。
深度防御原则与特定的控制或控制子集无关。它是指导应用程序选择控制的设计原则,以确保应用程序对不同形式的攻击具有弹性,并降低系统安全中单点故障的概率。
原则2:使用正向安全模型(白名单)
正向安全模型,通常称为白名单,定义了允许的内容,并拒绝所有不符合标准的内容。这种积极的模型应该与“消极的”(或“黑名单”)安全模型相对照,后者定义了什么是不允许的,而隐式地允许其他的一切。
应用软件开发中最常见的错误之一是急于“列举缺点”或开始使用黑名单。就像反病毒程序一样,已知的恶意代码(恶意软件)的特征被反病毒程序开发人员收集和维护,并在有更新时重新发布(这是相当频繁的);当更新签名文件和重新扫描系统以检测匹配新签名的任何东西时,这可能会导致操作和人员的大规模中断。
另一方面,白名单则侧重于“列举优点”,这是一项更容易实现的任务。程序员可以使用一个有限的列表,列出变量可能包含的值,并拒绝任何未出现在列表中的值。例如,Web应用程序中的一个常见漏洞是,当输入到表单字段时,无法检查可执行代码或HTML标记。如果表单的字段中只需要字母和数字字符,则程序员可以编写代码,在输入字符中逐个字符循环,以确定是否只有字母和数字。如果有数字和字母以外的输入,程序应该拒绝输入并强制重新输入数据。
原则3:安全地失败
安全地处理错误是安全和弹性应用程序的一个关键方面。有两种主要的错误需要特别注意:
在处理安全控制本身时发生的异常
与“安全性无关”的代码中的异常
重要的是,这些异常不能启用软件对策通常不允许的行为。作为开发人员,您应该考虑安全机制通常有三种可能的结果:
允许操作
不允许操作
异常
通常,您应该设计安全机制,使失败遵循与不允许操作相同的执行路径。例如,如果在处理过程中出现异常,诸如"isAuthorized"或"isAuthenticated"之类的安全方法都应该返回false。如果安全控制可以抛出异常,那么它们必须非常清楚该条件的确切含义。
原则4:以最小的权限运行
最小权限原则建议用户帐户拥有执行基本业务流程所需的最小权限。这包括用户权限和资源权限,例如:
CPU限制
内存
网络权限
文件系统权限
最小特权原则被广泛认为是增强数据和功能免受错误(即容错)和恶意行为(即计算机安全)保护的重要设计考虑因素。
最小特权原则也被称为最小权威原则(POLA)。
原则5:通过模糊来避免安全性
顾名思义,通过模糊安全性描述了基于查找或理解系统或应用程序中的安全机制的难度来维护系统或应用程序安全性的尝试。通过模糊实现的安全性依赖于确保系统或控制安全的实现的保密性。它被认为是一个薄弱的安全控制,当它是唯一的控制时,它几乎总是失败。
通过隐蔽性依赖安全性的系统可能存在理论上或实际的安全漏洞,但其所有者或设计者认为这些漏洞并不为人所知,而且攻击者不太可能发现它们。这种技术与设计上的安全性形成了鲜明的对比。
晦涩的安全性的一个例子是一个加密系统的开发者希望保持算法实现加密功能的一个秘密,而不是保持键一个秘密和发布算法,以便安全研究人员可以确定如果它足够防弹共同安全使用。
原则6:检测入侵
检测应用软件中的入侵需要三个要素:
能够记录安全相关事件
步骤,以确保定期监控日志
在检测到入侵后对其作出正确响应的过程
原则7:不要相信基础设施
您永远不会确切地知道您的应用程序将在什么硬件或操作环境上运行。依赖可能存在也可能不存在的安全流程或功能肯定会出现安全问题。确保通过应用程序代码或通过显式调用提供给应用程序开发人员供企业使用的可重用安全功能,显式地提供了应用程序的安全性需求。
原则8:不要信任服务
服务可以引用任何外部系统。许多组织使用第三方合作伙伴的处理功能,这些合作伙伴可能具有不同的安全策略和姿态,而且您不太可能影响或控制任何外部第三方,无论它们是家庭用户还是主要供应商或合作伙伴。因此,对外部运行的系统的隐式信任是不保证的。所有外部系统都应该以类似的方式处理。
例如,忠诚计划供应商提供网上银行使用的数据,提供奖励点数的数量和潜在兑换项目的小列表。在获得这些数据的程序中,您应该检查结果,以确保向最终用户显示结果是安全的(不包含恶意代码或操作),并且奖励点数是正数,并不是不可能的大(数据合理性)。
原则9:建立安全缺省值
默认情况下,每个应用程序都应该是开箱即用的安全交付!如果您的应用程序允许降低安全性,您应该让用户自己决定。默认安全意味着默认配置设置可能是最安全的设置——不一定是最用户友好的。例如,默认情况下应该启用密码老化和复杂度。用户可以关闭这两个功能,以简化应用程序的使用,并根据自己的风险分析和策略增加风险,但默认情况下不会强迫他们进入不安全状态。
编程最佳实践
除了上述原则之外,程序员还有一项特殊的职责,即确保设计规范是使用防御性编程实现的。防御性编程类似于防御性驱动,旨在将应用程序与使用时的疏忽或故意破坏活动隔离开来。
输入验证和处理
不正确的输入处理是当今应用程序中最常见的缺陷之一。处理不当的输入是系统和应用程序中存在关键漏洞的主要原因。
验证可以包括类型安全(整数、浮点数、文本等)和语法正确性的检查。应该检查字符串输入的长度(最小和最大字符数)和“字符集”验证,而数字输入类型(如整数和小数)可以根据可接受的值的上限和下限进行验证。当组合来自多个来源的输入时,应该对连接的结果执行验证,而不是单独对单个数据元素执行验证。这种做法有助于避免这样的情况:对单个数据项执行输入验证可能成功,但对来自所有数据源的连接字符串执行验证时失败。”(ref2)
有几种方法可以验证输入数据。每一种都有不同的安全级别,较好的安全级别遵循使用正向安全模型的实践,这在输入验证方法图中进行了说明。
避免跨站点脚本攻击
在跨站脚本(XSS)中,攻击者试图在应用程序的另一个用户的浏览器中注入客户端脚本代码。提交的注入代码将通过应用程序传递给受害用户。
以下技术可以相互结合使用来保护应用程序免受XSS攻击:
输出滤波
-编码字段以转义输出的HTML。
大多数语言都提供HTML编码的函数。
- HTML实体示例:
“>”字符被编码为>或>
强制在HTTP响应中使用"charset"编码。
内容类型:text / html;charset =(编码)
meta http-equiv="Content-Type"(…)charset=[encoding]/
饼干安全
-启用以下cookie标志:
HttpOnly
安全
防止注入攻击
有几种类型的注入攻击:SQL注入、LDAP注入、邮件命令注入、空字节注入、SSI注入、XPath注入、XML注入、XQuery注入等。在这里,我们将研究防止最有害的内容注入攻击——sql注入的技术。
验证应用程序接受的所有输入参数。
使用一种安全的方式来创建SQL查询——“PreparedStatement”或“CallableStatement”。
即使在没有输入验证的情况下,参数化查询也不容易受到SQL注入攻击。
-它们自动地将用户输入的范围限制为数据,并且输入永远不能被解释为SQL查询本身的一部分。
-它们可以对传递给查询对象的参数值执行数据类型检查。
如果您没有使用参数化查询,请考虑过滤所有潜在的危险字符:
单引号
- LIKE子句中的模式匹配字符(%,?,[,_)
认证和会话管理
在计算机系统中,有三种被广泛接受的识别个体的方法。您可以使用:
你知道的东西——你的密码
你拥有的东西——安全令牌设备或数字证书
你是你的指纹或视网膜扫描
处理非常敏感数据的应用程序应该考虑使用不止一种身份验证方法(“多因素身份验证”)——例如,需要安全令牌和密码或PIN号码(通常用于远程站点的公司VPN连接)。
建立用户的身份是加强特权和访问控制的关键。在不同的情况下,应用程序会要求用户提供一些身份证明:
登录
密码重置
在执行敏感事务之前
攻击者可以以不同的方式攻击其中的每一个,试图冒充合法的应用程序用户。攻击者希望获得用户在使用应用程序时可以访问的数据的访问权。
防御技术,以反击攻击登录功能,包括:
开发通用的“登录失败”消息,不表明用户名或密码是否错误。
在预定次数的失败登录尝试之后强制锁定帐户。
帐户锁定应触发通知发送给适当的人员,并应要求手动重置(通过帮助台)。
实现密码语法和强度(长度、字符复杂度要求等)的服务器端强制执行。
对抗密码重置攻击的防御措施包括:
考虑手动重置密码。自动密码重置机制可以极大地减少管理开销,但它们很容易被用于攻击。
要求用户回答一个开放式的安全问题,以启动密码重置。
考虑使用多个安全问题而不是一个。
一旦执行了重置,请生成一个强大且唯一的新密码,或者允许用户根据复杂性要求选择一个新密码。
当用户的密码被重置并使用该密码登录时,强制用户修改密码是用户唯一可以访问的功能。
访问控制
访问控制授权是系统确定特定用户是否具有对特定资源的访问权限的过程。要决定某个特定用户是否具有访问资源的权限,应用程序需要知道该用户的身份。许多应用程序使用“全有或全无”的方法,这意味着一旦通过身份验证,所有用户都有相同的特权权限。有几种实现访问特权和权限的策略。一种常见的方法是定义角色,为角色分配权限,并将用户放在这些角色中。
实现基于角色的访问控制,为应用程序用户分配权限。
在所有应用程序页面上执行一致的授权检查例程。(如果可能的话,应该在一个位置定义它,并在每个页面中调用或包含它。)
在适用的情况下,最后应用DENY特权,并根据具体情况发出ALLOW特权。
永远不要依靠模糊的安全性——假设攻击者能够猜出秘密细节。
将所有失败的访问授权请求记录到一个安全的位置,并确保定期检查这些日志。
错误处理