第1章 软件安全概述 1
1.1 软件 1
1.1.1 软件定义 1
1.1.2 软件分类 1
1.2 软件安全 3
1.2.1 软件安全概述 3
1.2.2 软件安全范畴 4
1.2.3 软件安全问题 5
1.3 本书的结构与内容 10
第2章 软件安全开发模型 13
2.1 软件开发模型 13
2.1.1 瀑布型软件开发模型 13
2.1.2 渐增型软件开发模型 14
2.1.3 变换型软件开发模型 14
2.2 常用软件开发方法 15
2.2.1 结构化软件开发方法 15
2.2.2 面向对象的软件开发方法 15
2.2.3 组件开发方法 16
2.2.4 敏捷软件开发方法(Scrum) 16
2.3 安全开发模型 17
2.4 微软安全开发生命周期模型 18
2.4.1 安全生命周期模型 18
2.4.2 SDL优化模型 18
2.4.3 SDL安全人员角色 19
2.4.4 SDL模型安全活动 20
2.4.5 培训阶段 23
2.4.6 需求阶段 23
2.4.7 设计阶段 24
2.4.8 实施阶段 25
2.4.9 验证阶段 25
2.4.10 发布和响应阶段 26
2.4.11 可选的安全活动 27
2.5 McGraw软件安全开发模型 28
2.5.1 代码审核(工具) 30
2.5.2 体系结构风险分析 30
2.5.3 渗透测试 31
2.5.4 基于风险的安全测试 31
2.5.5 滥用用例 31
2.5.6 安全需求 31
2.5.7 安全操作 31
2.6 NIST安全开发生命周期模型 32
2.6.1 开始阶段 33
2.6.2 获取与开发阶段 34
2.6.3 执行阶段 35
2.6.4 操作和维护阶段 36
2.6.5 部署阶段 36
2.7 CISAW软件安全开发模型 37
2.7.1 对象 37
2.7.2 生命周期 38
2.7.3 安全属性 38
2.7.4 五个环节 38
2.7.5 资源 39
2.7.6 管理 39
第3章 安全漏洞管理 40
3.1 概述 40
3.1.1 漏洞分类 40
3.1.2 漏洞等级 42
3.1.3 漏洞管理流程 44
3.1.4 漏洞管理机制 45
3.2 安全内容自动化协议(SCAP) 47
3.2.1 SCAP及其元素 48
3.2.2 可扩展配置检查列表描述格式XCCDF 50
3.2.3 开放漏洞评估描述语言OVAL 50
3.2.4 通用漏洞和披露列表CVE 51
3.2.5 通用平台枚举CPE 51
3.2.6 通用配置枚举CCE 52
3.2.7 通用漏洞评分系统CVSS 53
3.3 典型软件安全漏洞 53
3.3.1 缓冲区溢出漏洞 54
3.3.2 整数溢出漏洞 57
3.3.3 格式化字符串漏洞 58
3.3.4 指针覆盖漏洞 61
3.3.5 SQL注入漏洞 61
3.3.6 ByPass漏洞 63
3.3.7 信息泄露漏洞 64
3.3.8 越权漏洞 64
3.4 OWASP Top 10 64
3.4.1 注入攻击 65
3.4.2 失效的身份认证和会话管理 67
3.4.3 跨站脚本(XSS) 69
3.4.4 不安全的直接对象引用 71
3.4.5 安全配置错误 72
3.4.6 敏感数据暴露 74
3.4.7 功能级别访问控制缺失 75
3.4.8 跨站请求伪造(CSRF) 77
3.4.9 使用已知易受攻击组件 78
3.4.10 未验证的重定向和转发 79
第4章 安全功能设计 81
4.1 安全审计 82
4.1.1 安全审计自动响应 83
4.1.2 安全审计数据产生 83
4.1.3 安全审计分析 84
4.1.4 安全审计查阅 86
4.1.5 安全审计事件选择 87
4.1.6 安全审计事件存储 87
4.2 安全通信 88
4.2.1 原发抗抵赖 89
4.2.2 接收抗抵赖 90
4.3 密码支持 92
4.3.1 密钥管理 93
4.3.2 密码运算 96
4.4 用户数据保护 97
4.4.1 访问控制 99
4.4.2 数据流控制 102
4.4.3 数据鉴别 105
4.4.4 系统内部传送 106
4.4.5 残余信息保护 108
4.4.6 回退 109
4.4.7 存储数据的完整性 110
4.5 标识和鉴别(身份认证) 111
4.5.1 用户鉴别 112
4.5.2 用户标识 114
4.5.3 鉴别失败 115
4.5.4 用户属性定义 115
4.5.5 秘密的规范 116
4.5.6 主体—用户绑定 117
4.6 安全管理 117
4.6.1 功能的管理 118
4.6.2 安全属性的管理 119
4.6.3 数据的管理 120
4.6.4 安全管理角色 121
4.7 隐私保护 122
4.7.1 匿名 123
4.7.2 假名 124
4.7.3 不可关联性 125
4.7.4 不可观察性 126
4.8 安全功能的保护 127
4.8.1 底层抽象机测试 129
4.8.2 失效保护 130
4.8.3 安全功能数据的可用性 131
4.8.4 安全功能数据的保密性 131
4.8.5 安全功能数据的完整性 132
4.8.6 内部数据传送 133
4.8.7 物理保护 134
4.8.8 可信恢复 136
4.8.9 重放检测 139
4.8.10 引用仲裁 139
4.8.11 域分离 141
4.8.12 状态同步协议 142
4.8.13 时间戳 143
4.8.14 对外数据一致性 143
4.8.15 内部数据复制一致性 144
4.8.16 安全功能自检 144
4.9 资源利用 145
4.9.1 容错 146
4.9.2 服务优先级 147
4.9.3 资源分配 148
4.10 系统/子系统的访问 149
4.10.1 可选属性范围限定 150
4.10.2 多重并发会话限定 150
4.10.3 会话锁定 151
4.10.4 访问旗标 153
4.10.5 访问历史 153
4.10.6 会话建立 154
4.11 可信路径/信道 155
4.11.1 安全功能之间的可信信道 155
4.11.2 可信路径 156
第5章 常见安全问题 157
5.1 概述 157
5.2 常见编程安全问题分类 157
5.3 常见编程安全问题 159
5.3.1 整数赋值错误问题 159
5.3.2 整型提升导致的内存溢出错误 160
5.3.3 临时变量溢出 160
5.3.4 整数截断错误问题 161
5.3.5 整数溢出问题 161
5.3.6 带符号与无符号整型比较问题 162
5.3.7 size_t导致的死循环 162
5.3.8 误用short引起缓冲区溢出 163
5.3.9 表达式中对同一变量多次写入问题 164
5.3.10 空字符结尾错误问题 165
5.3.11 无界字符串复制问题 166
5.3.12 定长字符串越界问题 167
5.3.13 字符串截断问题 168
5.3.14 与函数无关的字符串错误问题 169
5.3.15 修改字符串常量错误问题 170
5.3.16 字符串比较错误 170
5.3.17 数组越界问题 172
5.3.18 数组定义和值初始化括号形式混淆错误 173
5.3.19 未正确区分标量和数组问题 173
5.3.20 二维数组的内存泄漏 174
5.3.21 释放指针指向的对象引起内存泄漏 175
5.3.22 数据指针被修改问题 176
5.3.23 函数指针被修改问题 177
5.3.24 删除void*指针错误 178
5.3.25 printf函数输出问题 179
5.3.26 格式化函数sprintf引起缓冲区溢出 180
5.3.27 指针变量的传值和传址混淆问题 180
5.3.28 验证方法参数问题 181
5.3.29 函数退出时内存未释放问题 182
5.3.30 continue和return混淆问题 183
5.3.31 非void返回类型函数问题 184
5.3.32 误用sizeof操作符取字符串长度 185
5.3.33 基类未定义虚析构函数引发错误 186
5.3.34 线程未join引起的内存泄漏 187
5.3.35 notify线程唤醒问题 188
5.3.36 多线程中Socket终止问题 190
5.3.37 程序异常退出时未关闭已打开文件 192
5.3.38 目录打开后未关闭 193
5.3.39 写文件没有调用fflush 193
5.3.40 临时文件未删除问题 194
5.3.41 敏感信息硬编码问题 196
5.3.42 引用未初始化的内存错误问题 197
5.3.43 检查和处理内存分配错误问题 198
5.3.44 执行零长度的分配错误问题 198
5.3.45 引用已释放内存的错误问题 199
5.3.46 双重释放内存错误问题 200
5.3.47 不匹配的内存管理函数问题 201
5.3.48 匿名对象引起的内存泄漏 201
5.3.49 JVM内存泄漏问题 203
5.3.50 覆盖equals方法而没有覆盖hashCode方法问题 204
5.3.51 finally程序段非正常退出问题 205
5.3.52 非泛型的数据类型问题 206
5.3.53 类名称比较问题 207
5.3.54 等同的对象得不到相等的结果问题 208
5.3.55 在嵌套类中暴露外部类的私有字段问题 209
5.3.56 静态方法隐藏问题 210
5.3.57 构造函数中抛出异常引发错误 211
5.3.58 构造器调用可覆盖方法问题 213
5.3.59 字符乱码问题 214
5.3.60 功能级别访问控制缺失问题 215
5.3.61 表单重复提交问题 217
5.3.62 不安全的直接对象引用问题 219
5.3.63 信息的不安全存储问题 220
5.3.64 SQL注入攻击 220
5.3.65 失效的身份认证和会话管理问题 222
5.3.66 跨站脚本(XSS) 223
第6章 安全编码实践 226
6.1 输入验证和数据合法性校验 226
6.1.1 输入数据有效性校验 226
6.1.2 避免SQL注入 227
6.1.3 避免XML注入 227
6.1.4 避免跨站脚本(XSS) 228
6.2 声明和初始化 228
6.2.1 避免类初始化相互依赖 228
6.3 表达式 229
6.3.1 勿忽略方法返回值 229
6.3.2 勿引用空指针 230
6.3.3 比较数组内容 230
6.4 数值类型和操作 230
6.4.1 防止整数溢出 230
6.4.2 避免除法和取模运算分母为零 232
6.5 类和方法操作 232
6.5.1 数据成员声明为私有且提供可访问的包装方法 232
6.5.2 敏感类不允许复制 232
6.5.3 比较类的正确做法 233
6.5.4 不要硬编码敏感信息 233
6.5.5 验证方法参数 234
6.5.6 勿使用过时或低效的方法 234
6.5.7 数组引用问题 235
6.5.8 勿产生内存泄漏 235
6.6 异常处理 236
6.6.1 不要忽略捕获的异常 236
6.6.2 不允许暴露异常的敏感信息 237
6.6.3 不允许抛出RuntimeException、Exception和Throwable 238
6.6.4 不要捕获NullPointerException或其他父类异常 239
6.7 多线程编程 240
6.7.1 确保被并发调用函数的可重入性 240
6.7.2 函数线程安全 242
6.7.3 确保共享变量的可见性 242
6.7.4 确保共享变量的操作是原子操作 244
6.7.5 Thread.run()和Thread.stop() 245
6.7.6 确保执行阻塞操作的线程可以终止 246
6.7.7 不在一个有限的线程池执行相互依存的任务 247
6.8 输入/输出 247
6.8.1 程序终止前删除临时文件 247
6.8.2 检测和处理文件相关错误 249
6.8.3 及时释放资源 249
6.9 序列化 250
6.9.1 不要序列化未加密的敏感数据 250
6.9.2 在序列化过程中避免内存和资源泄漏 251
6.9.3 反序列化要在程序最小权限的安全环境中进行 252
第7章 软件安全测试 253
7.1 软件安全测试方法 253
7.2 软件安全测试过程 254
7.3 软件安全测试组织 255
7.4 软件安全测试举例 257
7.4.1 测试对象 257
7.4.2 测试方法 257
7.4.3 测试过程 257
7.4.4 测试结果 260
7.4.5 安全建议 265
附录A 测试工具 267
F.1 源代码分析器Fortify SCA 268
F.1.1 Fortify SCA的工作原理 268
F.1.2 Fortify SCA支持的平台 268
F.1.3 Fortify SCA支持的编程语言 269
F.1.4 Fortify SCA可识别的安全漏洞 269
F.2 字节码扫描器——FindBugs 269
F.2.1 FindBugs的工作原理 269
F.2.2 FindBugs使用时机 269
F.3 数据库脆弱性扫描器——Database Scanner 270
F.3.1 Database Scanner的工作原理 270
F.3.2 Database Scanner支持的数据库 270
F.4 网络漏洞扫描器——NTOSpider 271
F.4.1 NTOSpider的工作原理 271
F.4.2 NTOSpider可识别的安全漏洞 271
F.5 网络漏洞扫描器——Metasploit 271
F.5.1 Metasploit的工作原理 272
F.5.2 Metasploit可识别的恶意软件 275
F.6 Web应用漏洞扫描器——AppScan 276
F.6.1 AppScan的工作原理 276
F.6.2 AppScan的主要功能 277
F.7 Web应用漏洞扫描器——JSky 279
F.7.1 JSky的工作原理 279
F.7.2 JSky可识别的安全漏洞 280
F.8 Web应用漏洞扫描器——WVS 280
F.8.1 WVS的工作原理 281
F.8.2 WVS可识别的漏洞 281
F.9 Web服务扫描器——SOATest 282
F.9.1 SOATest的工作原理 282
F.9.2 SOATest的主要功能 282
F.9.3 SOATest支持的平台 282
F.10 动态分析工具——CLR Profiler 282
F.10.1 CLR Profiler的工作原理 283
F.10.2 CLR Profiler可识别的问题 283
F.11 设计验证工具——SDMetrics 283
参考文献 285