首页>参考读物>计算机科学与技术>安全

编写安全的代码(第2版)
作者 : Michael Howard, David LeBlanc
译者 : 程永敬 翁海燕 朱涛江 等
丛书名 : 计算机科学丛书
出版日期 : 2004-11-24
ISBN : 7-111-11210-5
定价 : 55.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 480
开本 : 16开
原书名 : Writing Secure Code, Second Edition
原出版社: Microsoft Corporation.
属性分类: 店面
包含CD :
绝版 : 未绝版
图书简介

本书分为五部分。第一部分概括说明了保护系统安全的意义,以及设计安全系统的原则和所采用的技术;第二部分概括介绍了几乎适用于任何应用程序的重要编码技术;第三部分重点介绍了网络应用程序和.Net代码安全;第四部分讨论的安全问题在一般图书中少有论及,如测试、进行安全代码审查、隐私策略以及安全的软件安装等问题;第五部分是附录,分别介绍危险的API以及针对设计人员、开发人员和测试人员的安全措施核对清单。
  本书第1版曾作为Windows开发组全体成员的必读教材,而第2版更是总结了在针对微软产品的多次安全活动中的许多新发现。本书曾被比尔·盖茨指定为微软员工必读书籍,是软件设计、开发、测试、系统管理等人员必读的优秀教材。

图书特色

图书前言

在2002年2、3月份,人们都顾不上考虑Windows所有正常的安全特性了。在此期间,整个开发组的注意力都转向了如何提高此产品的下一版本—Windows Server 2003—的安全上。众所周知,“安全Windows倡议”的目的是使开发组成员了解最新的安全编码技术,从而找出设计缺陷、代码缺陷,改进测试代码和文档。在此期间,本书的第1版是Windows开发组全体成员的必读教材,而第2版收录了在这场活动中以及在针对微软其他产品的后续安全活动中的许多新发现,这些产品包括SQL Server、Office、Exchange、Systems management Server、Visual Studio .NET、.NET公共语言运行库,等等。
  Windows安全活动(以及许多其他的安全活动)的出发点,源于比尔·盖茨2002年1月15日发表的“可信计算”备忘录,其中概括说明了一种高级策略,即如何向用户提交更安全、更可靠的新型计算机系统。自从有了那个备忘录,我们已经与数千名开发人员交谈、合作过,而他们异口同声地说:“我们要做正确的事情……我们要开发安全的软件……但我们知道的还不够。”这种呼声是本书的直接催化剂:向他们传授学校里不教的技术—如何设计、生成、测试和注释安全的软件。所谓“安全的软件”,并不是指安全代码或实现安全特性的代码,而是指为抵挡恶意攻击而设计的代码。安全的代码也是健壮的代码。
  本书的目标是绝对要保证切实可行,书中可能使读者产生不安全感,可能会感到自己的代码也许会受到攻击。更确切地说,如果你创建的应用程序要运行在一台或多台计算机上,而这些计算机连到了网络上,或最大的网络Internet上,那么你的代码就可能会受到攻击。
  系统安全受到威胁后会造成各种严重后果,如生产力下降、信誉受损以及财产损失,如果攻击者能够破坏应用程序的安全(如,使之无法使用),你的客户就可能会转而使用竞争对手的产品。在使用基于Internet的服务时,大多数人都没有耐心,如果你的服务不好用,客户也会投奔你的竞争对手。
  对于众多软件开发商来说,真正的问题是,安全所带来的效益不像开发过程那样是显而易见的。因此,管理层不愿意在培训开发人员以编写安全的代码方面多花钱,在攻击得逞之前,他们不想在安全技术上投资。然而,亡羊补牢,则为时已晚。事后的修补工作,无论是在财力上还是在信誉上,都要付出高昂的代价。
  历史证明,最好的方法是保护财产,使之免遭盗窃和攻击。我们的祖先早就制定了对盗窃、损坏或侵占他人财物者的惩罚措施。的确,人们都明白,私人财物应当受到保护。这些道德准则也适用于数字世界;因此,作为开发人员,我们的部分职责就是创建可保护数字资产的应用程序和解决方案。
  本书包括一些基本概念,这些内容在学校课程里介绍“设计和构建安全的系统”主题时应当讲过。读者可能会认为,“设计”是设计人员或管理人员的事情,但作为开发人员和测试人员,同样也需要了解设计良好的系统结构以抵御攻击的有关过程。
  众所周知,无论花多少时间和精力来开发软件,开发出的软件仍然会存在漏洞,因为人们无法预测未来的安全问题。对于Windows Server 2003来说,同样也存在一些漏洞;但按照本书中所建议的方法,相信可以减少漏洞数,使黑客更难于发现和利用代码中的漏洞。

本书读者对象
  本书适用于设计应用程序或生成、测试以及注释解决方案的人员。如果编写基于Web或基于Win32的应用程序,或者正在学习或开发基于Microsoft .NET框架的应用程序,本书同样是很好的读物。总之,只要工作中涉及到应用程序开发,都会在本书中找到许多值得学习的内容。
  即使是正在编写不在Microsoft平台上运行的代码,书中的许多内容依然非常有用。除了个别几章是完全针对Microsoft平台以外,许多问题往往与平台无关。即便有时某种东西似乎仅适用于Windows,但其通常也有更加广泛的应用。例如,Everyone用户的“安全控制”访问控制列表和UNIX系统上设置为“全部可写”的文件,其实是同一问题,而跨网站的脚本问题是普遍存在的。

本书组织结构
  本书分为五个部分。第一部分(第1~4章)概括说明了为什么要保护系统安全免遭攻击,以及设计这种系统的原则和分析技术。
  第二部分和第三部分是本书的重点。第二部分(第5~14章)概括介绍了几乎适用于任何一种应用程序的重要的编码技术。第三部分(第15~18章)重点介绍了网络应用程序和.NET代码。
  第四部分(第19~24章)讲述了一般图书中很少讨论的一些主题,如测试、进行安全代码审查、隐私策略以及安全的软件安装等问题。第23章介绍了放在其他各章都不太合适的一些一般原则。
  第五部分是“附录”,包括5个附录,分别介绍危险的API,我们常听到的一些不考虑安全问题的荒谬借口,以及分别针对设计人员、开发人员和测试人员的安全措施核对清单。
  与其他作者不同,我们不仅告诉你应用程序如何不安全,而且告诉你为什么人们不愿意构建安全的系统。本书绝对实用,书中解释了系统怎样会受到攻击,人们常犯的错误,以及如何构建安全的系统—这才是最重要的。

安装和使用范例文件
  通过连接到站点http://www.microsoft.com/mspress/books/5957.asp,可以从Web上下载本书的范例文件(从Companion Content页下载)。要访问范例文件,请单击该页右侧More Information框中的Companion Content链接,打开Companion Content页,此页中包括下载范例文件的链接;也可以连接到Microsoft Press Support站点。下载链接可打开一个包含许可协议的可执行文件。要想把范例文件复制到硬盘上,请单击运行可执行文件的链接,然后接受许可协议。默认情况下,范例文件将被复制到My Document\Microsoft Press\Secureco2文件夹下。在安装过程中,可以改变目标文件夹。

系统要求
  尽管可以使用包括Visual C++6.0在内的大多数编译器来编译本书中用C/C++编写的大多数范例,但还是要求读者安装Microsoft Visual Studio .NET。用Perl编写的范例已经使用ActiveState Perl 5.6或ActivateState Visual Perl 1.0(可从http://www.activestate.com下载)测试过。VBScript和JScript代码已经用Windows Scripting Host测试过(Windows 2000及其以后的版本中包含Windows Scripting Host)。所有SQL范例都使用SQL Server 2000测试过。而Visual Basic .NET和Visual C#应用程序均是使用Visual Studio .NET编写和测试的。
  本书中的所有应用程序(有两个例外),均可以在符合建议的系统要求的、运行Windows 2000的计算机上运行。第7章的Safer范例和第11章的utf8 MultiByteToWideChar范例,必须在Windows XP或Windows Server 2003上才能正确运行。编译代码时必须使用更加健壮的机器(即比编译器所要求的基本条件更优)。

作者简介

Michael Howard, David LeBlanc:Michael Howard: <<Designing Secure Web-Based for Microsoft Windows 2000>>的作者,致力于安全设计、安全编程和安全测试-这些都是Microsoft Windows开发小组中“安全Windows倡导活动“的一部分。他也是Microsoft安全系列推广活动的架构师之一。
David LeBlanc: Microsoft可信计算倡导活动的关键成员,致力于网络安全、编写网络审计工具、内部渗透测试的推广等。

译者简介

程永敬 翁海燕 朱涛江 等:暂无简介

图书目录

第一部分 现 代 安 全
第1章 对安全系统的需求 2
1.1 “疯狂的Web网”上的应用程序 3
1.2 可信计算的需要 4
1.3 让每个人都参与进来 5
1.3.1 巧妙地向企业推销安全 5
1.3.2 使用搞破坏的方法 7
1.4 灌输安全意识的一些主意 8
1.4.1 让老板发一封电子邮件 9
1.4.2 任命安全宣传员 9
1.5 攻击者的优势和防御者的劣势 12
1.5.1 因素1:防御者必须对所有的环节都进行防御,而攻击者可以选择最薄弱的环节12
1.5.2 因素2:防御者只能针对已知的攻击进行防御,而攻击者则可以探测未知的漏洞13
1.5.3 因素3:防御者必须永远保持警惕,而攻击者却可以随意“罢工”13
1.5.4 因素4:防御者的活动必须遵循相应的规则,而攻击者则可以采用一些卑鄙的手段13
1.6 本章小结 13
第2章 主动的安全开发过程 14
2.1 不断改进开发过程 15
2.2 安全教育的角色 15
2.2.1 强制培训的阻力 17
2.2.2 不断更新的培训 18
2.2.3 安全科学的进步 18
2.2.4 教育证明“更多的眼睛”不代表更安全 18
2.2.5 有力的证据! 19
2.3 设计阶段 19
2.3.1 面试期间的安全问题 19
2.3.2 定义产品的安全目标 20
2.3.3 安全是产品的一种特性 22
2.3.4 要有足够的时间考虑安全问题 24
2.3.5 安全的设计源于威胁建模 24
2.3.6 终结不安全的特性 24
2.3.7 设置bug门槛 24
2.3.8 安全小组审查 25
2.4 开发阶段 25
2.4.1 只有核心成员能够查看新代码(签字确认) 25
2.4.2 新代码的同级安全审查(签字确认) 25
2.4.3 定义安全的编码准则 26
2.4.4 审查旧的缺陷 26
2.4.5 外部安全审查 26
2.4.6 安全推动活动 26
2.4.7 留心自己的错误数量 27
2.4.8 记录错误 27
2.4.9 没有惊喜,也没有圣诞节彩蛋! 27
2.5 测试阶段 28
2.6 发行和维护阶段 28
2.6.1 如何知道已完成 28
2.6.2 响应过程 28
2.6.3 责任制 29
2.7 本章小结 29
第3章 赖以生存的安全法则 30
3.1 设计安全、默认安全和部署安全 30
3.1.1 设计安全 30
3.1.2 默认安全 31
3.1.3 部署安全 31
3.2 安全法则 31
3.2.1 从错误中吸取教训 32
3.2.2 尽可能缩小攻击面 33
3.2.3 采用安全的默认设置 34
3.2.4 纵深防御 35
3.2.5 使用最小特权 36
3.2.6 向下兼容总是不安全的 37
3.2.7 假设外部系统是不安全的 38
3.2.8 失败时的应对计划 38
3.2.9 失败时进入安全模式 38
3.2.10 切记:安全特性不等于安全的特性 40
3.2.11 决不要将安全仅维系于隐匿 40
3.2.12 不要将代码与数据混在一起 40
3.2.13 正确地解决安全问题 40
3.3 本章小结 41
第4章 威胁建模 42
4.1 通过威胁建模进行安全的设计 42
4.1.1 成立威胁建模小组 43
4.1.2 分解应用程序 44
4.1.3 确定系统所面临的威胁 49
4.1.4 以风险递减的顺序给威胁分级 54
4.1.5 选择应付威胁的方法 63
4.1.6 选择缓和威胁的方法 64
4.2 安全技术 64
4.2.1 身份认证 64
4.2.2 授权 68
4.2.3 防篡改和增强保密性的技术 69
4.2.4 保护秘密或最好不要保存秘密 69
4.2.5 加密、散列、MAC和数字签名 69
4.2.6 审核 70
4.2.7 过滤、节流和服务质量 70
4.2.8 最小特权 70
4.3 缓和工资表范例程序的威胁 71
4.4 各种威胁及解决方案 71
4.5 本章小结 71
第二部分 安全的编码技术
第5章 头号公敌:缓冲区溢出 76
5.1 堆栈溢出 77
5.2 堆溢出 83
5.3 数组下标错误 87
5.4 格式字符串错误 89
5.5 Unicode和ANSI缓冲区大小不匹配 93
5.6 预防缓冲区溢出 95
5.6.1 字符串处理方面的安全问题 96
5.6.2 关于字符串处理函数的警告 103
5.7 Visual C++ .NET的/GS选项 104
5.8 本章小结 106
第6章 确定适当的访问控制 107
6.1 ACL何以如此重要 107
6.2 ACL的组成 109
6.3 选择好的ACL的方法 111
6.4 创建ACL 113
6.4.1 在Windows NT 4中创建ACL 113
6.4.2 在Windows 2000中创建ACL 116
6.4.3 用活动模板库创建ACL 119
6.5 对ACE进行正确的排序 120
6.6 留意终端服务器和远程桌面的SID 122
6.7 NULL DACL和其他的危险ACE类型 123
6.7.1 NULL DACL和审核 124
6.7.2 危险的ACE类型 124
6.7.3 如果无法改变NULL DACL该怎么办 125
6.8 其他的访问控制机制 125
6.8.1 .NET框架角色 126
6.8.2 COM+角色 127
6.8.3 IP限制 127
6.8.4 SQL Server触发器和权限 128
6.8.5 一个医学方面的示例 128
6.8.6 关于访问控制机制的重要说明 129
6.9 本章小结 130
第7章 以最小特权运行 131
7.1 现实中的最小特权 131
7.1.1 病毒和特洛伊木马 132
7.1.2 破坏Web服务器 132
7.2 访问控制简介 133
7.3 特权简介 133
7.3.1 SeBackupPrivilege问题 134
7.3.2 SeRestorePrivilege问题 136
7.3.3 SeDebugPrivilege问题 136
7.3.4 SeTcbPrivilege问题 136
7.3.5 SeAssignPrimaryTokenPrivilege和SeIncreaseQuotaPrivilege问题 137
7.3.6 SeLoadDriverPrivilege问题 137
7.3.7 SeRemoteShutdownPrivilege问题 137
7.3.8 SeTakeOwnershipPrivilege问题 137
7.4 令牌简介 137
7.5 令牌、特权、SID、ACL和进程之间的关系 138
7.6 应用程序要求提高特权的三个理由 139
7.6.1 ACL问题 139
7.6.2 特权问题 140
7.6.3 使用LSA秘密 140
7.7 解决提高特权的问题 140
7.7.1 解决ACL问题 140
7.7.2 解决特权问题 141
7.7.3 解决LSA问题 141
7.8 确定适当特权的过程 141
7.8.1 步骤1:找到应用程序使用的资源 141
7.8.2 步骤2:找到应用程序使用的特权API 142
7.8.3 步骤3:哪一个帐户是必需的 142
7.8.4 步骤4:获取令牌的内容 143
7.8.5 步骤5:所有SID和特权是否都是必需的 147
7.8.6 步骤6:调整令牌 148
7.9 Windows XP和Windows Server 2003中的低特权级服务帐户 158
7.10 模拟特权和Windows Server 2003 159
7.11 调试最小特权问题 160
7.11.1 为什么以普通用户运行时应用程序失败 160
7.11.2 如何判断应用程序失败的原因 160
7.12 本章小结 165
第8章 加密的弱点 166
8.1 使用不良的随机数 166
8.1.1 问题:rand函数 166
8.1.2 Win32中的加密随机数 168
8.1.3 托管代码中的加密随机数 172
8.1.4 Web页中的加密随机数 172
8.2 使用口令生成加密密钥 173
8.3 密钥管理问题 174
8.3.1 长期密钥和短期密钥 175
8.3.2 使用合适的密钥长度保护数据 176
8.3.3 将密钥保存在靠近数据源的地方 176
8.3.4 密钥交换问题 179
8.4 创建自己的加密函数 180
8.5 使用相同的流密码加密密钥 181
8.5.1 人们为什么使用流密码 182
8.5.2 流密码的缺陷 182
8.5.3 如果必须使用相同的密钥怎么办 184
8.6 针对流密码的位替换攻击 185
8.6.1 解决位替换攻击 185
8.6.2 何时使用散列、密钥散列或数字签名 186
8.7 重用明文和密文的缓冲区 190
8.8 使用加密技术缓和威胁 191
8.9 在文档中说明你使用的加密算法 191
8.10 本章小结 191
第9章 保护机密数据 192
9.1 攻击机密数据 192
9.2 有时并不需要保存秘密 193
9.2.1 创建干扰散列 193
9.2.2 使用PKCS #5增加攻击的难度 194
9.3 获取用户的秘密信息 195
9.4 保护Windows 2000及其以后版本中的秘密信息 196
9.5 保护Windows NT 4中的秘密信息 199
9.6 保护Windows 95/98/ME/CE中的秘密 202
9.7 不要选择最低共同点解决方案 205
9.8 管理内存中的秘密 206
9.8.1 编译器优化警告 207
9.8.2 对内存中的机密数据进行加密 210
9.9 锁定内存以防敏感数据被分页 211
9.10 保护托管代码中的机密数据 211
9.11 提高安全门槛 217
9.11.1 把数据存储在FAT系统的文件中 217
9.11.2 使用嵌入密钥和XOR对数据进行编码 217
9.11.3 使用嵌入密钥和3DES加密数据 218
9.11.4 使用3DES加密数据并把密码存放在注册表中 218
9.11.5 使用3DES加密数据并把强密钥存储在注册表中 218
9.11.6 使用3DES加密数据,把强密钥存储在注册表中,并使用ACL控制文件和注册表218
9.11.7 使用3DES加密数据,把强密钥存储在注册表中,要求用户输入密码,并使用ACL控制文件和注册表项 218
9.12 保护机密数据时的折衷方案 218
9.13 本章小结 219
第10章 一切输入都是有害的 220
10.1 问题 220
10.2 误信他人 221
10.3 防御输入攻击的策略 222
10.4 如何检查合法性 223
10.5 Perl中被污染的变量 225
10.6 使用正则表达式检查输入 225
10.7 正则表达式和Unicode 228
10.8 正则表达式的“罗塞塔石碑” 231
10.8.1 Perl中的正则表达式 231
10.8.2 托管代码中的正则表达式 231
10.8.3 脚本中的正则表达式 232
10.8.4 C++中的正则表达式 232
10.9 不使用正则表达式的最佳做法 233
10.10 本章小结 234
第11章 规范表示的问题 235
11.1 规范的含义及其存在的问题 235
11.2 规范文件名的问题 235
11.2.1 绕过Napster名称过滤 235
11.2.2 Apple Mac OS X和Apache的漏洞 236
11.2.3 DOS设备名漏洞 236
11.2.4 Sun公司的StarOffice /tmp目录的符号链接漏洞 236
11.2.5 常见的Windows规范文件名错误 237
11.3 基于Web的规范问题 241
11.3.1 绕过AOL的父母控制 241
11.3.2 绕过eEye的安全检查 241
11.3.3 安全区域和IE4的“无点IP地址”错误 242
11.3.4 IIS 4.0的::$DATA漏洞 242
11.3.5 何时一行变成了两行 244
11.3.6 另一个Web问题—转义 244
11.4 视觉等效攻击和同形异义词攻击 247
11.5 预防规范化错误 247
11.5.1 不要根据文件名进行决策 247
11.5.2 使用正则表达式限制文件名的格式 248
11.5.3 停止生成8.3格式的文件名 249
11.5.4 不要相信PATH环境变量,要使用完整的路径名 249
11.5.5 尝试规范化文件名 249
11.5.6 安全地调用CreateFile 252
11.6 基于Web的规范化问题的补救措施 253
11.6.1 限制合法输入 253
11.6.2 处理UTF-8字符时要谨慎 253
11.6.3 ISAPI—岩石和硬地之间 254
11.7 最后的考虑:非基于文件的规范化问题 254
11.7.1 服务器名 254
11.7.2 用户名 255
11.8 本章小结 257
第12章 数据库输入问题 258
12.1 问题 258
12.2 伪补救措施1:用引号将输入括起来 260
12.3 伪补救措施2:使用存储过程 260
12.4 补救措施1:永不以sysadmin身份连接 261
12.5 补救措施2:以安全的方式创建SQL语句 262
12.6 纵深防御示例 263
12.7 本章小结 266
第13章 Web特有的输入问题 267
13.1 跨网站脚本:输出何时变坏了 267
13.1.1 有时攻击者不需要<SCRIPT>块 270
13.1.2 攻击者不需要用户点击链接! 270
13.2 与XSS有关的其他攻击 270
13.2.1 针对本地文件的XSS攻击 270
13.2.2 针对HTML资源的XSS攻击 272
13.3 XSS的补救措施 272
13.3.1 将输出编码 272
13.3.2 为所有的标签属性加上双引号 272
13.3.3 将数据插入innerText属性 273
13.3.4 强制使用代码页 273
13.3.5 IE 6.0 SPI的cookie选项HttpOnly 274
13.3.6 IE的“Web标记” 275
13.3.7 IE的<FRAME SECURITY>属性 276
13.3.8 ASP.NET 1.1的ValidateRequest配置选项 276
13.4 不要只是寻找不安全的结构 277
13.5 我只是想让用户向我的Web站点发送HTML 278
13.6 如何审查代码中的XSS错误 279
13.7 基于Web的其他安全主题 279
13.7.1 eval()可能是坏的 279
13.7.2 HTTP信任问题 279
13.7.3 ISAPI应用程序和过滤器 280
13.7.4 警惕“可预知的Cookie” 282
13.7.5 SSL/TLS客户端的问题 283
13.8 本章小结 283
第14章 国际化问题 284
14.1 I18N安全的黄金准则 284
14.2 在应用程序中使用Unicode 284
14.3 预防I18N缓冲区溢出 285
14.4 验证I18N 286
14.4.1 视觉验证 286
14.4.2 不要使用LCMapString验证字符串 286
14.4.3 使用CreateFile验证文件名 286
14.5 字符集转换问题 287
14.6 调用MultiByteToWideChar时使用MB_PRECOMPOSED和MB_ERR_INVALID_CHARS 287
14.7 调用WideCharToMultiByte时使用WC_NO_BEST_FIT_CHARS445 287
14.8 比较和排序 289
14.9 Unicode字符属性 290
14.10 规范化 291
14.11 本章小结 291
第三部分 更安全的编码技术
第15章 Socket安全 294
15.1 避免服务器被劫持 294
15.2 TCP窗口攻击 300
15.3 选择服务器接口 300
15.4 接受连接 300
15.5 编写防火墙友好的应用程序 304
15.5.1 只用一个连接工作 305
15.5.2 不要要求服务器连接回客户端 305
15.5.3 使用基于连接的协议 305
15.5.4 不要通过另外一个协议使你的应用程序进行多路复用 306
15.5.5 不要在应用层数据中嵌入主机IP地址 306
15.5.6 让你的应用程序可配置 306
15.6 欺骗、基于主机和基于端口的信任 306
15.7 IPv6即将到来 307
15.8 本章小结 308
第16章 RPC、ActiveX控件和DCOM安全 309
16.1 RPC入门 309
16.1.1 什么是RPC 310
16.1.2 创建RPC应用程序 310
16.1.3 RPC应用程序的通信原理 311
16.2 RPC安全最佳实践 312
16.2.1 使用/robust MIDL开关参数 312
16.2.2 使用[range]属性 313
16.2.3 要求对连接进行验证 313
16.2.4 使用数据包的保密性和完整性 317
16.2.5 使用严格的上下文句柄 318
16.2.6 不要依靠上下文句柄来进行访问检查 319
16.2.7 注意空的上下文句柄 320
16.2.8 不要信任你的对等端 321
16.2.9 使用安全回调 321
16.2.10 在单一进程中驻留多个RPC服务器 323
16.2.11 使用主流的协议 324
16.3 DCOM安全最佳实践 325
16.3.1 DCOM基础 325
16.3.2 应用层的安全 326
16.3.3 DCOM用户上下文环境 326
16.3.4 可编程实现的安全性 328
16.3.5 源端和接收端 331
16.4 ActiveX入门 331
16.5 ActiveX安全最佳实践 331
16.5.1 什么样的ActiveX组件是初始化安全和脚本安全的 332
16.5.2 初始化安全和脚本安全的最佳实践 333
16.6 本章小结 335
第17章 拒绝服务攻击的防范 336
17.1 应用程序失败攻击 336
17.2 CPU不足攻击 339
17.3  内存不足攻击 344
17.4  资源不足攻击 345
17.5  网络带宽攻击 346
17.6  本章小结 346
第18章 编写安全的.NET代码 348
18.1  代码访问安全概述 349
18.2  FxCop:“必备的”工具 350
18.3  程序集是强命名的 351
18.4  指定程序集权限需求 352
18.4.1  请求最小的权限集 353
18.4.2  拒绝不必要的权限 353
18.4.3  请求可选的权限 353
18.5  过分热衷于使用Assert方法 354
18.6  关于Demand和Assert方法的进一步信息 355
18.7  及时禁用断言 356
18.8  请求和链接请求 357
18.9  慎用SuppressUnmanagedCodeSecurityAttribute属性 358
18.10  远程请求 359
18.11  限制代码的使用范围 359
18.12  不要在XML或配置文件中存储敏感数据 360
18.13  审查允许部分信任的程序集 361
18.14  检查非托管代码的托管包装的正确性 362
18.15  委托的问题 362
18.16  序列化的问题 362
18.17  隔离存储的作用 363
18.18  在部署ASP.NET应用程序之前禁用跟踪和调试 364
18.19  不要远程发布冗长的错误信息 364
18.20  对来源不可信的数据进行反序列化 365
18.21  失败时不要让攻击者知道太多 365
18.22  本章小结 366
第四部分 特殊的安全问题
第19章  安全性测试 368
19.1  安全性测试人员的角色 368
19.2  安全性测试与一般测试的区别 368
19.3  根据威胁模型制定安全性测试计划 369
19.3.1  分解应用程序 369
19.3.2  确定组件接口 370
19.3.3  按照潜在的漏洞对接口进行分级 371
19.3.4  确定每一个接口使用的数据结构 371
19.3.5  STRIDE类型的攻击程序 372
19.3.6  用数据变种攻击应用程序 373
19.3.7  测试之前 381
19.3.8  开发查找缺陷的工具 381
19.4  用欺诈性的服务程序测试客户软件 394
19.5  用户是否应看到或修改数据 395
19.6  用安全模板进行测试 395
19.7  发现一个错误时测试并未结束 396
19.8  测试码应有很高的质量 397
19.9  测试端到端解决方案 397
19.10  确定攻击面 397
19.10.1  确定根攻击向量 398
19.10.2  确定攻击向量的偏差 398
19.10.3  统计产品中有偏差的攻击向量 398
19.11  本章小结 399
第20章 审查安全代码 400
20.1 处理大型应用程序 401
20.2 多遍审查方法 401
20.3 从易处着手 402
20.4 整数溢出 403
20.5 检查返回结果 405
20.6 对指针代码进行额外的审查 406
20.7 绝不要相信网络上的数据 406
20.8 本章小结 407
第21章 安全的软件安装 408
21.1 最小特权原则 408
21.2 安装后立即清除密码 410
21.3 使用安全配置编辑器 410
21.4 低层的安全API 415
21.5 使用Windows Installer 416
21.6 本章小结 416
第22章 在应用程序中加入隐私策略 417
22.1  对隐私的恶意侵犯和令人讨厌的侵犯 417
22.2  主要的隐私立法 417
22.2.1  个人身份信息 418
22.2.2  关于数据保护的欧盟法令 418
22.2.3  安全海港原则 418
22.2.4  其他隐私立法 419
22.3  隐私与安全 419
22.4  建立隐私基础设施 420
22.4.1  首席隐私官的作用 420
22.4.2  隐私倡导者的作用 421
22.5  设计尊重隐私的应用程序 421
22.5.1  在开发过程中加入隐私策略 421
22.5.2  了解隐私的特点 423
22.6  本章小结 429
第23章  常用的好做法 430
23.1 不要向攻击者透露任何信息 430
23.2 关于服务的最佳做法 430
23.2.1 安全、服务和交互式桌面 430
23.2.2 服务帐户准则 431
23.3 不要以标志字符串的形式泄漏信息 433
23.4 在补丁中改变错误信息时要谨慎 433
23.5 复查错误路径 433
23.6 让它保持关闭 433
23.7 核心态错误 433
23.7.1 高级安全问题 433
23.7.2 句柄 434
23.7.3 符号链接 434
23.7.4 配额 435
23.7.5 序列化原语 435
23.7.6 缓冲区处理问题 435
23.7.7 IRP取消 436
23.8 在代码中添加关于安全的注释 437
23.9 借助于操作系统的功能 437
23.10 不要依赖用户去做正确的选择 437
23.11 安全地调用CreateProcess函数 438
23.11.1 不要将lpApplicationName设置为NULL 439
23.11.2 用引号把lpCommandLine中可执行文件的路径括起来 439
23.12 不要创建共享的/可写的代码段 439
23.13 正确使用模拟函数 440
23.14 不要将用户文件写入\Program Files目录 440
23.15 不要把用户数据写入HKLM 440
23.16 不要以“完全控制”权限打开对象 441
23.17 对象创建错误 441
23.18 慎用CreateFile 442
23.19 安全地创建临时文件 443
23.20 Setup程序和EFS文件系统的问题 445
23.21 文件系统重解析点问题 445
23.22 客户端安全是自相矛盾的说法 446
23.23 范例就是模板 446
23.24 以身作则,亲身体验 447
23.25 你得向用户负责 447
23.26 基于管理员SID确定访问权限 447
23.27 允许使用长口令 448
23.28  慎用_alloca 448
23.29  ATL转换宏 449
23.30 不要嵌入公司的名称 449
23.31 将字符串移至资源DLL中 450
23.32 应用程序日志 450
23.33 从危险的C/C++迁移到托管代码 450
第24章  编写安全文档和错误消息 451
24.1  文档中的安全问题 451
24.1.1  关于文档的基础知识 451
24.1.2  通过文档缓和威胁 452
24.1.3  编写安全性文档的最佳做法 452
24.2  错误消息中的安全问题 453
24.3  典型的安全消息 454
24.4  信息泄漏问题 454
24.4.1  知情同意 455
24.4.2  累进泄漏 456
24.4.3  消息要具体 456
24.4.4  最好不要提问 457
24.5  对安全消息进行可用性测试 458
24.6  审阅产品说明书时的注意事项 458
24.7  安全设置的可用性 458
24.8  本章小结 459
第五部分 附   录
附录A  危险的API 462
附录B  安全误区 469
附录C  设计人员的安全措施核对清单 473
附录D  开发人员的安全措施核对清单 474
附录E  测试人员的安全措施核对清单 477
最后的一点思考 478
参考文献 479

教学资源推荐
作者: [美]斯瓦鲁普·布尼亚(Swarup Bhunia) 马克·特赫拉尼普尔(Mark Tehranipoor) 著
作者: 邹德清 代炜琦 金海 著
作者: 蔡晶晶 李炜 主编
参考读物推荐
作者: 刘焱 编著
作者: Simson Garfinkel, Gene Spafford, Alan Schwartz