软件安全特性
- C.I.A
- 机密性(Confidentiality)
- 完整性(Integrity)
- 可用性(Availability)
- TripleA
- 身份认证(Authentication)
- 授权(Authorization)
- 审核(Auditing)
- Others
- 会话管理(Session Management)
- 错误处理(Error And Exception Handing)
概述
机密性 Confidentiality
需考量三个方面
传输时
- 考虑加密传输
HTTPS的应用尤为明显
处理时
- 站点防护。数据在使用者端时,是否可以进行适当防护措施
最常见的是密码输入框的*号符,及填写表单时常见的遮罩层
- 信任边界。数据跨域系统不同信任层级时,所应考量的验证机制
常见于新注册一个账号后,首次登录时进行的严密验证
- 收集数据的必要性。网站是否有取得该数据的充分理由
以前的网站在注册账号总是会填写一堆信息,现在则是分散式的,敏感数据多是在个人中心可以设置
存储时
- 存储加密
完整性 Integrity
确保完整性的三个重要手段
输入验证机制 Input Validation
- 原则是 All Input is Evil,即所有外部输入都是预设不合法的。在此前提之下,以黑白名单,过滤规则等手段验证输入数据的合法性。
常见的如防XSS跨站脚本攻击,即攻击者在链接中插入恶意代码,就能够盗取用户信息。攻击者通常会用十六进制(或其他编码方式)将链接编码,以免用户怀疑它的合法性。网站在接收到包含恶意代码的请求之后会产成一个包含恶意代码的页面,而这个页面看起来就像是那个网站应当生成的合法页面一样。
校验机制 Checksum
- 利用杂凑函数(求对象Hash值)对数据产生理论上独一无二的杂凑值作为数位指纹,用来识别数据传输前后是否遭到篡改。校验原则是数据与其杂凑值若要提供另一方进行验证,必须进行传输加密或透过不同管道分别提供数据与杂凑值。
需要注意的是,Hash函数有简单的如Java原生的hashCode方法,复杂的有MD系列或是SHA系列的。前者可能会发生Hash碰撞,而后者几乎不会有Hash碰撞的情况发生
译者目前使用Fedora系统。这类开源镜像提供站点一般都是提供镜像ISO文件和校验码文本。而曾经Fedora的官方源就发生过ISO镜像和校验码文本都被替换的情况,导致用户下载了带有植入代码的Fedora镜像安装使用。数位签证 Digital Signature
- 同时采用非对称式密钥确保身份验证及不可否认性,也采用杂凑确保数据完整性,因此重要网站交易行为应考虑采用数位签证方式,将交易相关数据由该使用者的私钥进行签证保存,以作为交易有效的重要证据。
这个应用非常广泛,使用过Github的就知道在创建仓库时都是要将公钥提交网站保存的
可用性 Availability
常用的概念或机制如下
高可用性 High Availability 或容错 Fault Tolerance
- 目的是防范单点失效 Single Point of Failure, SPOF。单点失效指软体架构中某个节点发生故障或错误时,将导致整个系统全面停摆。若软体设计上未进行备用 Redundancy 设计处理,每个阶段的节点只有一套的状况下,很容易发生单点失效状况。
高可用性的系统通常采用分布式架构或主从架构等方式。如常用的数据库的主从机制,Redis集群节点搭建等等。容错 Fault Tolerance 则代表更进一步的,当节点发生错误故障时,其它节点有能力将错误节点当下进行的任务继续完成
负载均衡 Load Balance 或集群 Cluster
- 提高可用性的一点是使用备份机制,如下
- 完整备份。完整的备份所有在覆盖范围里的数据
- 差异备份。仅备份自上次完整备份以来差异的部分
- 增量备份。仅备份自上次备份以来差异的部分
使用过Git工具的对以上三种备份应该很了解了。git clone 一个仓库可以看作是完整备份,日常的git add则可以看作差异备份
- 提高可用性的一点是使用备份机制,如下
身份验证 Authentication
类型可分为如下三种
验证使用者知道的某事
事前设定的密码,对于某个特定问题的答案等
验证使用者拥有的某物
某特殊装置令牌Token,凭证,简讯(拥有特定手机号码),电子邮件(拥有特定邮件地址)
验证使用者本身特征
使用者指纹,虹膜识别,人脸识别等
由于账号密码仍为目前大多数网站常用的主要身份验证机制,针对账号密码的攻击也相当常见,建议配合以下方式
账户锁定机制 Account Lockout
使用者输入账号密码验证错误达到一定次数后,将其锁定一段时间,禁止其登录网站。目前常用的是禁止IP登录,然而有心攻击的人可以利用Header的 X-Forwarded-For参数来伪造IP,因此IP锁定不一定可靠。
防止自动化程序机制 Captcha
全名为 Completely Automated Public Turing test to tell Computers and Humans Apart【全自动区分电脑和人类的图灵测试】。设计用来区分进行动作的主体是否为自然人。由于攻击账号密码分身验证机制通常采用编写的程序实现,因此可以使用CAPTCHA防范。目前对于这个的发展,译者只了解到所谓的验证码。验证码经历了图片式,手机/邮箱接收式和滑动式等发展,其中图片式已经有大部分可以通过机器学习进行识别,目前应用广泛的属于接收式和滑动式了。
设定密码强度与定期更换原则
授权 Authorization 与存取控制 Access Control
考量原则如下
最小权限
赋予使用者权限时,应考虑其目的与必要性,给予最短时间内,必须且最少的权限
职责分离
将一件任务或功能所需要的主体条件设定为两个以上,且需要满足所有条件才能得以完成。
完全仲裁
每一次主体存取网站资源时,网站作为中介,检查主体是否具有合法授权。可参考典型的中间人攻击 Man in the Middle, MITM
授权与存取控制机制应采用集中控制管理方式,于服务器端过滤所有请求,以避免被绕过检查或由于人为疏忽而未纳入原本应在检查范围内的资源
这里参考典型的RBAC(Role-Based Access Control【基于角色的权限访问控制】)的设计原则
最小权限原则
之所以被RBAC所支持,是因为RBAC可以将其角色配置成其完成任务所需要的最小的权限集。
责任分离原则
可以通过调用相互独立互斥的角色来共同完成敏感的任务而体现,比如要求一个计帐员和财务管理员共参与同一过帐。
数据抽象
可以通过权限的抽象来体现,如财务操作用借款、存款等抽象权限,而不用操作系统提供的典型的读、写、执行权限。然而这些原则必须通过RBAC各部件的详细配置才能得以体现。
审核 Auditing 与记录 Logging
网站常常发生的与之相关的问题
- 未完整保留记录,导致否认行为 Repudiation
- 记录不必要数据,导致数据泄漏 Information Disclosure
- 网站错误或备份失误导致记录丧失
一个完整的网站使用记录可考虑包含以下内容
- 身份识别:唯一身份识别ID,会话SessionID等
- 时间:网站主机时定自动校时,记录时间单位准确至毫秒
- 当前进行的操作描述
- 相关对象数据:记录对交易追踪及排错有帮助的物件值
- 位置资讯:来源与目的端的网络地址
会话管理 Session Management
常见的会话攻击及防范措施如下
推测Session ID
尽量使用服务器内建的Session ID产生管理方式,尽可能将Session ID设定为容许的最大长度,以确保Session ID的随机性而不易被推测
窃取Session ID
Session ID产生后需要传送给客户端,后续也会重复地在前后端来回传输,还会暂时存储在客户端,因此攻击者可以在传输过程或是先通过入侵客户端来窃取Session ID。因此,传输Session ID的过程建议加密,并且限制客户端对Session ID的存取方式
置换Session ID
攻击者先登录网站,取得合法的Session ID后,再以各种可能的方式置换掉其它使用者的Session ID,该使用者登录后,攻击者已知的这个Session ID便具有使用者的权限,可以直接拿来使用。
错误及例外处理 Error and Exception Handling
建议采用错误及例外处理方法如下
- 防止直接显示详细错误讯息
记录详细讯息,显示错误代码
捕捉例外后,应该尽可能Log记录系统当下相关详细资讯,包含使用者ID/SessionID【避免多人共用同一账号,造成无法归责状况】,行为描述,时间,网络地址,对象信息。
考虑是否再次抛出错误
撰写工具类或底层程序时,需考虑发生例外情况时,除了捕捉例外并进行详细记录外,还需要考虑是否再次抛出例外,避免严重错误被底层程序逻辑就此掩盖,开发人员不知道错误发生地。
一致的Log机制并区分严重等级
将未预料错误设定为Error等级,将有可能导致后续错误或资料数值异常情况设置为Warn等级,将需要从正式上线环境中得知的Log资讯设置为Info等级以上,将需要从测试或开发环境中得知的详细Log资讯设置为Debug等级以上。
避免安静无声的错误,采用通知机制
严重的错误发生时,若开发者仅仅将其捕捉后,输出Log信息到文件,则通常不会发现系统错误发生,因为程序逻辑可能仍然持续进行,因此可能造成安静无声的错误,持续不停在网站中发生。因此,在进行例外处理时,考量严重的错误情况,应该采用其它通知机制,例如邮件等。
正确释放资源
OWASP Top10 - 2017年
级别 | 翻译 |
---|---|
A1 | 注入攻击 - injection:输入的数据变成执行命令的一部分,没有正确的隔离执行命令与数据,导致改变命令本身含义或改变查询结果 |
A2 | 有缺陷的身份验证和会话管理 - Broken Authentication and Session Management:许多网站使用自定义的身份验证机制和会话管理机制,由于操作不正确,导致攻击者可以取得密码,身份凭证或攻击操作上的弱点,以此假冒登录者身份 |
A3 | XSS跨战脚本攻击 - Cross-Site Scripting(XSS):网站缺乏有效的输入验证,攻击者将恶意程序码作为输入内容植入网页或URL,客户端浏览时执行恶意程序 |
A4 | 有缺陷的访问控制 - Broken Access Control |
A5 | 安全配置错误 - Security Misconfiguration:网站部署与执行环境是整个网站安全的一部分,包含第三方元件/函数库,开发框架,程序执行环境,应用程序服务器,生产环境等。这些环境的设定若没有正确的配置或采用不安全的预设配置,将会导致数据泄漏 |
A6 | 敏感数据泄漏 - Sensitive Data Exposure:网站若没有正确识别敏感数据并在适当时机加密保护,或者不正确的加密机制,都有可能导致数据泄漏 |
A7 | 攻击防范不周 - Insufficient Attack Protection |
A8 | 跨站请求伪造 - Cross-Site Request Forgery(CSRF) |
A9 | 使用有漏洞的组件 - Using Components with Known Vulnerabillities |
A10 | API保护不当 - Underprotected APIs |
以上是2017新推出的OWASP前10大漏洞,后文根据各个模块分别详细讲述,笔记内容并不是2017年的,所以有所差别。
摘取部分CWE项目
CWE-434 未限制危险型档案上传
网站提供上传功能,不能仅仅检查文档类型的后缀名,应检查并限制档案的格式内容。Java 7版本之后可采用Files.probeContentType方法进行检查
CWE-120 缓冲区复制时未检查输入的大小
属于缓冲区溢出问题。Java目前没有手动配置记忆体,没有这种风险
CWE-494 下载代码未进行完整性检查
攻击者可以置换来源档案的手法很多,因此从其它来源取得执行档案,需要进行完整性检查。网站提供下载档案应采用演算法产生杂凑值供使用者比对其完整性
CWE-829 从非信任来源纳入功能
典型的WEB 2.0安全问题。整合多个数据来源或功能的混搭手法,若来源不明,可能导致网站包含或执行恶意程序代码。尽可能避免以自动化方式。使用无法验证内容的资料来源,或者每次使用前检查其内容
CWE-676 使用可能有危险的功能
多数程序语言的API或函数库中,皆包含一些被发现有安全问题的功能或方法,开发者应避免使用这些功能。
CWE-131 未正确计算缓冲区大小
某些程序语言中(例如C语言),内存需要手动配置,未正确计算使用的正确大小会导致缓冲区溢出问题
CWE-134 未控制的格式化字符串功能
某些程序语言中,格式化字符串的功能容易受到攻击者操纵,造成恶意代码被输入并执行,应尽量避免类似功能从外部取得数据
CWE-190 整数溢出问题
Java数字形态有上下限问题,输入作为计算的一部分需要特别注意是否可能发生溢出问题。另外,数字型态有所谓Wraparound特性,即最大值加一会等于该数字型态的最小值。
这是个人观点及学习笔记,参考蔡宗霖先生的《Java网站安全防护实务手册》