1.身份认证
在需求分析阶段,应明确定义系统必须或可以达到的身份认证功能。
必须的安全要求:
- 账户管理方式
账户的产生、修改、变更、删除以及身份认证应采用统一的身份认证平台来实现。
- 认证失败后的处理方式设计,防止黑客暴力猜测。
连续失败登录后锁定账户。账户锁定后可以由系统管理员解锁,也可以在一段时间后自动解锁。
- 区分公共区域和受限区域
将站点分割为公共访问区域和受限访问区域,受限区域只能接受特定用户的访问,而且用户必须通过站点的身份验证。当未经认证的用户试图访问受限资源时,应用应自动提示用户认证。
- 使用强密码策略
内部系统的口令规则需要符合口令管理规则, 要求输入至少 8 位字符,其中要包含大写字母、小写字母、数字和特殊字符。
- 能够禁用账户
在系统受到威胁时使凭证失效或禁用账户,则可以避免遭受进一步的攻击。
- 不在用户存储中存储密码
如果必须验证密码,可以不实际存储密码。相反,可以存储一个单向哈希值,然后使用用户所提供的密码重新计算哈希值。为减少对用户存储的词典攻击威胁,可以使用强密码,并将随机 salt 值与该密码结合使用。
- 支持密码有效期
密码不应固定不变,而应作为常规密码维护的一部分,通过设置密码有效期对密码进行更改。
- 不在网络上以纯文本形式发送密码
以纯文本形式在网络上发送的密码容易被窃听。为了解决这一问题,应确保通信通道的安全,例如,使用 SSL 对数据流加密。
- 保护身份验证 Cookie
身份验证 cookie 被窃取意味着登录被窃取。可以通过加密和安全的通信通道来保护验证凭证。另外,还应限制验证凭证的有效期,以防止因重复攻击导致的欺骗威胁。
- 同一用户同时只允许登录一个
对进入保护区域的用户需要进行重新认证(比如从普通用户操作改变到管理员级别权限的操作、修改个人密码的操作)。
- 不使用多重关键字查找
使用多重关键字查找用户记录可能会导致SQL或LDAP注入问题。比如同时使用用户名和密码作为键来查找用户记录,且不检测SQL或LDAP注入,则任一字段都可能产生风险。
推荐的安全要求
- 用户名的选择
如果用户名是可预测的,那就很可能遭到攻击者攻击。例如,如果银行仅仅使用的顺序增长的客户名或者号码作为访问的账户,就特别有风险。
- 使用验证码
使用图片验证码的可以防止账户暴力破解。
2.授权
- 应用软件应包含用户权限分配和管理功能设计。如:
- 系统读、写、执行权限设计。
- 系统查看、配置、修改、删除、登录、运行等权限设计。
- 数据访问范围的权限设计
- 应用功能模块使用权限的设计
- 限制用户对系统级资源的访问(系统级资源包括文件、文件夹、注册表项、Active Directory 对象、数据库对象、事件日志等。)
- 应用使用的数据库账户必须是普通权限账户,只能访问允许的数据库;
- 应用启动进程的权限应遵循“最小授权”原则
应用使用的系统账号(运行环境中的)应遵循“最小授权”原则。不使用“Administrator”, “root”, “sa”, “sysman”, “Supervisor”或其它所有的特权用户被用来运行应用程序或连接到网站服务器,数据库,或中间件。
- 最小授权粒度尽
调用方被映射到应用程序逻辑中间层中的角色,并基于角色成员身份限制对类和方法的访问权限。使用由当前调用方的角色成员身份所确定的有限标识集来执行下游资源访问。
- 在条件允许的情况下,尽量采用统一的访问控制机制。
3.输入和输出验证
正确的输入验证是防御目前应用程序攻击的最有效方法之一。正确的输入验证是防止 XSS、SQL 注入、缓冲区溢出和其他输入攻击的有效对策。
- 对所有的输入进行安全验证
开始输入验证时,首先假定所有输入都是恶意的,除非有证据表明它们并无恶意。无论输入是来自服务、共享文件、用户还是数据库,只要其来源不在可信任的范围之内,就应对输入进行验证。
- 采用集中验证方法
将输入验证策略作为应用程序设计的核心元素。考虑集中式验证方法,例如,通过使用共享库中的公共验证和筛选代码。这可确保验证规则应用的一致性。此外,还能减少开发的工作量,且有助于以后的维护工作。
- 在服务器端进行验证
应使用服务器端代码执行其自身的验证。使用客户端验证可以造成攻击者绕过客户端或关闭客户端脚本例程(例如,通过禁用JavaScript 脚本)。
- 注意标准化问题
标准化是指将数据转化为标准形式的过程。接受输入文件名、URL或用户名时必须先进行标准化。
- 限制、拒绝和净化输入
输入验证的首选方法是从开始就限制允许输入的内容。按照已知的有效类型、模式和范围验证数据。使用以下策略:
-
- 限制输入
定义一个筛选器,根据类型、长度、格式和范围来筛选输入的数据。定义应用程序字段可以接受的数据输入,并强制应用该定义。拒绝一切有害数据。
-
- 验证数据的类型、长度、格式和范围
在适当的地方对输入数据使用强类型检查,检查字符串字段的长度,检查字符串的格式是否正确。
-
- 拒绝已知的有害输入
要拒绝有害数据,需假定应用程序知道恶意输入的所有变体。
-
- 净化输入
向客户端写回数据时,对用户输入的数据进行 HTML 编码和 URL 编码检查,过滤特殊字符(包括HTML关键字以及&,\r\n,两个\n等字符)。
- SQL注入防范
进行数据库操作的时候,对用户提交的数据必须过滤 ’ ; -- 等特殊字符。
- XML注入防范
当使用XML文件格式存储数据时,若使用Xpath和XSLT功能,必须过滤用户提交数据中的< > / ' = " 等字符。
4.配置管理
必须的安全要求:
- 确保配置存储的安全
基于文本的配置文件、注册表和数据库是存储应用程序配置数据的常用方法。应避免在应用程序的 Web 空间使用配置文件,以防止可能出现的服务器配置漏洞导致配置文件被下载。应避免以纯文本形式存储机密,如数据库连接字符串或账户凭据。通过加密确保这些项目的安全,然后限制对包含加密数据的注册表项、文件或表的访问权限。
- 使用最少特权进程和服务账户
应用程序配置的一个重要方面是用于运行 Web 服务器进程的进程账户,以及用于访问下游资源和系统的服务账户。应确保为这些账户设置最少特权。
推荐的安全要求:
- 确保管理界面的安全
配置管理功能只能由经过授权的操作员和管理员访问,在管理界面上实施强身份验证,如使用证书。如果有可能,限制或避免使用远程管理,并要求管理员在本地登录。如果需要支持远程管理,应使用加密通道,如 SSL 或 VPN 技术,因为通过管理界面传递的数据是敏感数据。
- 单独分配管理特权
如果应用程序的配置管理功能所支持的功能性基于管理员角色而变化,则应考虑使用基于角色的授权策略分别为每个角色授权。
5.敏感数据保护
应用软件应包含数据安全设计:包括数据库的安全、数据采集、数据传输、数据处理、数据存储、数据备份和恢复的安全。对重要的、敏感数据应进行加密和完整性保护。
处理诸如地址、档案等用户私人信息的应用程序应该采取专门的步骤,来确保这些数据的保密性,并确保其不被修改。
- 尽量避免存储机密
在软件中以完全安全的方式存储机密是不可能的。可以接触到服务器的系统管理员可以访问这些数据。例如,当仅仅是验证用户是否知道某个机密时,则没有必要存储该机密。在这种情况下,可以存储代表机密的哈希值,然后使用用户提供的值计算哈希值,以验证该用户是否知道该机密。
- 不要在代码中存储机密
不要在代码中对机密进行硬编码。即使不将源代码暴露在 Web 服务器上,但从编译过的可执行文件中仍然可以提取字符串常量。配置漏洞可能会允许攻击者检索可执行文件。
- 不要在永久性 cookie 中存储敏感数据
避免在永久性 cookie 中存储敏感数据。如果存储的是纯文本数据,最终用户能够看到并修改该数据。如果对其加密,必须考虑密钥管理。
- 不要使用 HTTP-GET 协议传递敏感数据
避免使用 HTTP-GET 协议存储敏感数据,因为该协议使用查询字符串传递数据。使用查询字符串不能确保敏感数据的安全性,因为查询字符串经常被服务器记录下来。
- 对数据进行加密或确保通信通道的安全
如果在网络上向客户端发送敏感数据,应对数据进行加密或确保通信通道的安全。通常的做法是在客户端与 Web 服务器之间使用 SSL。当应用系统无法达到此要求时可以通过网络访问控制等手段限制可以访问应用系统的用户。
6.会话管理
应能设置系统会话时间,防止会话劫持和重复攻击的风险。
- 限制会话寿命
对于高度保护的应用系统,可将超时时间设置为5分钟,低风险的应用系统设置不能超过20分钟。
- 对身份验证 cookie 的内容进行加密
如果Cookie信息包含了身份验证信息,则必须对 cookie 内容进行加密。
7.加密
- 不使用自创加密方法
成功开发出加密算法和例程是非常难的。因此,应尽量使用平台提供的经过验证和测试的加密服务。
- 使用正确的算法和密钥大小
选择了正确的算法非常重要,另外,应确保所使用的密钥大小能提供足够的安全级别。密钥越大,安全性越高。
- 确保加密密钥的安全
加密密钥是输入加密及解密进程的秘密数字。为保证加密数据的安全,必须保护好密钥
8.参数保护
- 机密敏感的 cookie 数据保护
Cookie 中可能包含敏感数据,如会话标识符或用作服务器端授权进程一部分的数据。要保护该类型数据,应使用加密方法对 cookie 的内容加密。
- 确保用户没有绕过检查
确保用户没有通过操作参数而绕过检查。防止最终用户可以通过浏览器地址文本框操作 URL 参数。
- 验证从客户端发送的所有数据
限制可接受用户输入的字段,并对来自客户端的所有值进行验证。
- 不信任 HTTP 头信息
HTTP 头在 HTTP 请求和响应开始时发送。应确保 Web 应用程序的任何安全决策都不是基于 HTTP 头中包含的信息,因为攻击者很容易操作 HTTP 头。
9.异常管理
- 不要向客户端泄漏信息
发生故障时,不要暴露将会导致信息泄漏的消息。例如,不要暴露包括函数名以及调试内部版本时出问题的行数的堆栈跟踪详细信息。应向客户端返回一般性错误消息。
- 记录详细的错误信息
向错误日志发送详细的错误消息。应该向服务或应用程序的客户发送最少量的信息,如一般性错误消息和自定义错误日志 ID,随后可以将这些信息映射到事件日志中的详细消息。确保没有记录密码或其他敏感数据。
- 捕捉异常
使用结构化异常处理机制,并捕捉异常现象。这样做可以避免将应用程序置于不协调的状态,这种状态可能会导致信息泄漏。它还有助于保护应用程序免受拒绝服务攻击。
10.日志
未来应用的访问审计开发必须支持SOC安全平台。
- 明确审计日志格式
审计日志的格式强烈建议使用单行的,有规则,有格式的CSV文本格式。但也可以是下列方式中的一种。
- Syslog方式:Syslog方式需要给出syslog的组成结构。
- Snmp方式:Snmp方式需要同时提供MIB信息。
- 日志记录事件应至少包含以下事件:
- 审计功能的启动和关闭;
- 应用系统的启动和停止;
- 配置变化;
- 访问控制信息,比如:
- 由于超出尝试次数的限制而引起的拒绝登录;
- 成功或失败的登录;
- 用户权限的变更;
- 用户密码的变更;
- 授权用户执行了角色中没有明确授权的功能;
- 用户试图执行角色中没有明确授权的功能。
- 用户账户的创建;
- 用户账户的注销;
- 用户账户的冻结;
- 用户账户的解冻。
- 用户对数据的异常操作事件,包括:
- 不成功的存取数据尝试;
- 数据标志或标识被强制覆盖或修改;
- 对只读数据的强制修改;
- 来自非授权用户的数据操作;
- 特别权限用户的活动。
- 审计日志应至少包含如下内容:
- 用户ID或引起这个事件的处理程序ID
- 事件的日期、时间(时间戳)
- 事件类型
- 事件内容
- 事件是否成功
- 请求的来源(例如请求的IP地址)
- 审计日志应禁止包含如下内容:
- 用户敏感信息(如密码信息等)
- 客户完整交易信息
- 客户的隐私信息(如、密码信息、身份信息等)
- 审核并记录跨应用层的访问
审核并记录跨应用层的访问,以便用于认可。考虑应用程序如何在多重应用层间传送调用方标识。
- 确保日志数据的安全
限制对日志数据的访问,加大了攻击者篡改日志数据以掩饰其攻击行为的难度。应将有权操作日志数据的个人数量减到最小。只为高度信任的账户(如管理员)授予访问权限。
- 定期备份和分析日志数据
如果从不对日志数据进行分析,则记录活动没有任何意义。应定期(至少一月一次)备份生产服务器上的日志数据。
11.反调试技术
所有供客户下载的程序(客户端)必须具有反调试技术。