编写安全的代码

编写安全的代码
作 者: Michael Howard David LeBlanc
出版社: 清华大学出版社
丛编项: 软件项目管理世界经典教材丛书
版权说明: 本书为公共版权或经版权方授权,请支持正版图书
标 签: 网络安全
ISBN 出版时间 包装 开本 页数 字数
未知 暂无 暂无 未知 0 暂无

作者简介

暂缺《编写安全的代码》作者简介

内容简介

《编写安全的代码》中文版本书的两位作者是曾经击败过世界上最难缠的恶意黑客的代码武士,他们在书中披露了经过实战考验的保护代码安全的各种绝招。比尔·盖茨将此书钦定为“微软员工必读”。本书分为五大部分。第一部分介绍了为什么要保护系统安全,使用权之免遭攻击,以及设计这种系统的原则和分析技术。第二部分和第三部分是本书的重点,分别介绍了几乎适用于任何一种应用程序的关键性安全编码技术,以及网络应用程序和.NET代码安全技术。第四部分讲述了一些特殊的、在一般的图书中很少讨论的安全问题。第五部分包括5个附录,分别介绍危险的API以及安全措施核对清单等。本书告诉您应用程序怎么会不完全,为什么人们不愿意构建安全的系统,最重要的是如何构建安全的系统。本书是软件设计、开发、测试、系统管理等人同必读的教材,也是软件学院、计算机专业或软件公司首选的软件安全教材。

图书目录

第I部分 当前的安全问题

第1章 人们对安全的系统的需求

“野蛮网”上的应用程序

对值得信赖的计算的需求

在游戏中干掉对手

巧妙地向企业推销安全

通过颠覆推销安全

灌输安全意识的一些主意

向老板发送E-mail

推荐一名安全传道士

攻击者的优势和防御者的困境

根源1:防御者必须防御所有的点而攻击者可以选择最弱的点

根源2:防御者只能防御已知的攻击而攻击者可以刺探未知的弱点

根源3:防御者必须始终保持警惕而攻击者可以随意地攻击

根源4:防御者必须遵守游戏规则而攻击者可以不守规矩

本章小结

第2章 主动的安全开发过程

不断改进开发过程

安全教育的角色

强制培训的阻力

不断更新的培训

安全科学的进步

教育证明“更多的眼睛”不代表更安全

有力的证据!

设计阶段

访问调查期间的安全问题

定义产品的安全目标

安全是产品的一种特性

要有足够的时间考虑安全问题

安全的设计源于威胁建模

终结不安全的特性

设置Bug栏

安全小组审阅

开发阶段

只有核心成员能够查看新代码(签字确认)

新代码的同级安全审查(签字确认)

定义安全的编码准则

审查旧的缺陷

外部安全审直

安全运动

留心自己的错误数量

记录错误

没有惊喜,也没有礼物

测试阶段

发货和维护阶段

如何知道已完成

响应过程

责任制

本章小结

第3章 赖以生存的安全法则

设计、默认和部署安全(SD3)

设计安全

默认安全

部署安全

安全法则

从错误中吸取教训

尽可能缩小攻击面

采用安全的默认设置

纵深防御

使用最小的特权

向下兼容总是令人伤心

假设外部系统是不安全的

故障的应对计划

安全模式失败

切记:安全特性!=安全的特性

决不要将安全仅维系于隐匿

不要将代码与数据混合在一起

正确地解决安全问题

本章小结

第4章 威胁建模

通过威胁建模进行安全的设计

成立威胁建模小组

分解应用程序

确定系统所面临的威胁

按风险大小依次排列威胁

选择应付威胁的方法

选择缓和威胁的技术

安全技术

身分验证

授权

防篡改和增强保密性的技术

保护秘密或最好不要保存秘密

加密、哈希、MAC和数字签名

审核

筛选、截流和服务质量

最小特权

缓和工资表范例程序的威胁

各种威胁及解决方案

本章小结

第II部分 安全的编码技术

第5章 1号公敌:缓冲区溢出

堆栈溢出

堆溢出

数组下标错误

格式字符串错误

Unicode和ANSI缓冲区大小不匹配

一个真实的Unicode错误示例

预防缓冲区溢出

安全的字符串处理

关于字符串处理函数的警告

Visual C++ .NET的/GS选项

本章小结

第6章 确定适当的访问控制

ACL何以如此重要

题外话:修复注册表代码

ACL的组成

选择好的ACL的方法

有效的拒绝ACE

创建ACL

在Windows NT 4中创建ACL

在Windows 2000中创建ACL

用活动模板库创建ACL

正确排序ACE

留意终端服务器和远程桌面的SID

NULL DACL和其他的危险ACE类型

NULL DACL和审核

DangerousACETypes

如果无法改变NULL DACL该怎么办

其他的访问控制机制

.NET框架的角色

COM+的角色

IP限制

SQL Server触发器和权限

一个医学方面的示例

关于访问控制机制的重要说明

本章小结

第7章 以最小特权运行

现实中的最小特权

病毒和特洛伊木马

丑化Web服务器

访问控制简介

特权简介

SeBackupPrivilege问题

SeRestorePrivilege问题

SeDebugPrivilege问题

SeTcbPrivilege问题

SeAssignPrimaryTokenPrivilege问题

SeLoadDriverPrivilege问题

seRemoteShutdownPrivilege问题

SeTakeOwnershipPrivilege问题

令牌简介

令牌、特权、SID、ACL和进程之间的关系

SID和访问检查,特权和特权检查

应用程序要求提高特权的三个理由

ACL例题

特权问题

使用LSA秘密

解决提高特权的问题

解决ACL例题

解决特权问题

解决LSA问题

确定适当特权的过程

步骤1:找到应用程序使用的资源

步骤2:找到应用程序使用的特权API

步骤3:哪一个账户是必需的

步骤4:获取今牌的内容

步骤5:所有SID和特权是否都是必需的

步骤6:调整令牌

Windows XP和Windows.NET Server 2003中的低特权服务账户

模拟特权和Windows.NET Server 2003

调试最小特权问题

为什么以普通用户运行时应用程序失败

如何判断应用程序失败的原因

本章小结

第8章 加密的弱点

使用不良的随机数

问题:rand

Win32中的加密随机数

托管代码中的加密随机数

Web页中的加密随机数

使用密码导出加密密钥

测量密码的有效位长度

密钥管理问题

长期密钥和短期密钥

使用合适的密钥长度保护数据

将密钥保存在靠近数据源的地方

密钥交换问题

创建自己的加密函数

使用相同的流码加密密钥

人们为何使用流码

流码的缺陷

如果必须使用相同的密钥怎么办

针对流码的位翻转攻击

解决位翻转攻击

何时使用哈希、键控哈希或数字签名

重用明文和密文的缓冲区

使用加密技术援和威胁

在文档中说明你使用的加密算法

第9章 保护机密数据

攻击机密数据

有时并不需要保存秘密

创建伪装的哈希

使用PKCS#5增加攻击的难度

获取用户的秘密

保护Windows 2000及其以后版本中的秘密

特殊案例:Windows XP中的客户证书

保护Windows NT 4中的秘密

保护Windows 95/98Me/CE中的秘密

使用PnP获得设备的详细资料

不要选择最小公分母解决方案

管理内存中的秘密

编译器优化停止警告

对内存中的机密数据进行加密

锁定内存以防敏感数据被分页

保护托管代码中的机密数据

管理托管代码存放在内存中的秘密

提高安全门槛

把数据存储在FAT文件中

使用嵌入密钥和XOR对数据进行编码

使用嵌入密钥和3DES加密数据

使用3DES加密数据并把密码存放在注册表中

使用3DES加密数据并把强密钥存储在注册表中

使用3DES加密数据把强密钥存储在注册表中并使用ACL控制文件和注册表项

使用3DES加密数据把强密钥存储在注册表中要求用户输入密码并使用ACL

控制文件和注册表项

保护机密数据时的折衷方案

本章小结

第10章 一切输入都是有害的

问题

误信他人

防御输入攻击的策略

如何检查合法性

Perl中被污染的变量

使用正则表达式检查输入

仔细检查发现的数据是否有效

正则表达式和Unicode

正则表达式的“罗塞塔石碑”

Perl中的正则表达式

托管代码中的正则表达式

脚本中的正则表达式

C++中的正则表达式

不使用正则表达式的最佳做法

本章小结

第11章 规范表示的问题

规范的含义及其存在的问题

规范文件名的问题

绕过Napster名称过滤

AppleMacOSX和Apache的弱点

DOS设备名的弱点

Sun公司的StarOffice/tmp目录的符号链接的弱点

常见的Windows规范文件名错误

基于Web的规范问题

绕过AOL的父母控制

绕过eEye的安全检查

安全区域和IE 4的“无点IP地址”错误

IIS 4.0的::$DATA的弱点

何时一行变成了两行

另一个Web问题——换码

视觉等效攻击和同形异义词攻击

预防规范化错误

不要根据文件名进行决策

使用正则表达式限制文件名的格式

停止生成8.3格式的文件名

不要相信PATH环境变量——使用完整的路径名

尝试规范化文件名

安全地调用CreateFile

基于Web的规范化问题的补救措施

限制合法输入

处理UTF-8字符时要谨慎

ISAPI——岩石和硬地之间

最后的考虑:非基于文件的规范化问题

服务器名

用户名

本章小结

第12章 数据库输入问题

问题

伪补救措施1:用引号把输入括起来

伪补救措施2:使用存储过程

补救措施1:永不以Sysadmin身份连接

补救措施2:以安全的方式创建SQL语句

以安全的方式创建SQL存储过程

深层防御示例

本章小结

第13章 Web特有的输入问题

跨网站脚本:输入何时变坏了

有时攻击者不需要<SCRIPT>块

攻击者不需要用户单击链接!

与XSS有关的其他攻击

针对本地文件的XSS攻击

针对HTML资源的XSS攻击

XSS的补救措施

将输出编码

在所有标记属性两端添加双引号

将数据插入innerText属性

强制使用代码页

IE 6.0 SPI的cookie选项HttpOnly

IE的“Web标记”

IE的<FRAME SECURITY>属性

ASP.NET 1.1的ValidateRequest配置选项

不要指望不安全的构造

我只是想让用户向我的Web站点发送HTML

如何审查代码中的XSS错误

基于Web的其他安全主题

eval()可能是坏的

HTTP信任问题

ISAPI应用程序和筛选器

警惕“可预知的Cookie”

SSL/TLS客户端的问题

本章小结

第14章 国际化问题

118N安全的黄金准则

在应用程序中使用Unicode

预防118N缓冲区溢出

字和字节

验证118N

可视验证

不要使用LCMapString验证字符串

使用CreateFile验证文件名

字符集转换问题

调用MultiByteToWideChar时使用MB_PRECOMPOSED和MB_HRR_INVALID_CHARS

调用WideCharToMultiByte时使用WC_NO_BEST_FIT_CHARS445比较和排序

Unicode字符属性

范式

本章小结

第III部分 更安全的编码技术

第15章 套接字安全

避免服务器劫持

TCP窗口攻击

选择服务器接口

接受连接

编写防火墙友好的应用程序

只使用一个连接

不要求服务器从后端连接到客户机

使用基于连接的协议

不要在另一个协议上多路复用应用程序

不要把主机的IP地址嵌入应用层数据

使应用程序成为可配置的

电子欺骗与基于主机和基于端口的信任

IPv6即将发布

本章小结

第16章 保护RPC、ActiveX控件和DCOM

RPC入门

什么是RPC

创建RPC应用程序

RPC应用程序如何通信

安全的RPC的最佳做法

使用/robust MIDL开关

使用[range]属性

要求身份验证的连接

使用数据包隐私和完整性

使用严谨的上下文句柄

不要将访问检查依赖于上下文句柄

警惕NULL上下文句柄

不要信任对等机

使用安全回调

多台RPC服务器驻留在同一进程内意味着不安全

使用主流的协议

安全的DCOM的最佳做法

DCOM基础

应用层安全

DCOM用户上下文

可编程的安全设置

源端和接收端

ActiveX入门

安全的ActiveX的最佳做法

对于初始化和脚本来说ActiveX组件是否安全

初始化和脚本安全的最佳做法

本章小结

第17章 防止拒绝服务攻击

应用程序失败攻击

CPU饥饿攻击

内存不足攻击

资源不足攻击

网络带宽攻击

本章小结

第18章 编写安全的.NET代码

代码访问安全概述

FxCop:“必备的”工具

程序集是强命名的

强命名程序集和ASP.NET

指定程序集权限要求

请求最小的权限集

拒绝不必要的权限

请求可选的权限

过分热衷于使用Assert方法

关于Demand和Assert方法的进一步信息

及时禁用断言

请求和链接请求

LinkDemand安全错误示例

慎用SuppressUnmanagedCodeSecurityAttribute属性

远程请求

限制代码的使用范围

不要在XML或配置文件中存放敏感数据

审查允许部分信任的程序集

检查非托管代码的托管包装的正确性

委托的问题

序列化的问题

隔离存储的作用

在部署ASP.NET应用程序之前禁用跟踪和调试

不要远程发布冗长的错误信息

反序列化来源不可信的数据

失败时不要让攻击者知道太多

本章小结

第IV部分 特殊的安全问题

第19章 安全性测试

安全性测试人员的任务

安全性测试各不相同

根据威胁模型制订安全性测试计划

分解应用程序

确定组件接口

按照受攻击的可能性大小排列接口

确定每一个接口采用的数据结构

用STAIDE威胁攻击应用程序

用数据变种攻击应用程序

测试之前

开发查找缺陷的工具

用无赖服务器测试客户机

用户是否应看到或修改数据

用安全模板进行测试

发现一个错误时测试并未结束

测试码应具有很高的质量

测试端到端解决方案

确定攻击面

确定根攻击向量

确定攻击向量的偏差

统计产品中有偏差的攻击向量

本章小结

第20章 审查安全码

处理大型应用程序

多程方法

从易处着手

整数上溢

一个相关的问题:整数下溢

检查返回结果

对指针代码进行额外的审查

决不要相信网络上的数据

本章小结

第21章 安全的软件安装

最小特权原则

安装后立即清除密码

使用安全配置编辑器

低级安全API

使用WindowsInstaller

本章小结

第22章 在应用程序中加入隐私策略

对隐私的恶意侵犯和令人讨厌的侵犯

主要的隐私立法

个人身份信息

关于数据保护的欧盟法令

安全海港原则

其他隐私立法

隐私与安全

建立隐私基础设施

隐私长官的角色

隐私拥护者的角色

设计尊重隐私的应用程序

在开发过程中加入隐私策略

了解隐私的特点

本章小结

第23章 常见的好的做法

不要向攻击者透露任何信息

关于服务的最佳做法

安全、服务和交互式桌面

服务账户准则

不要以条幅字符串的形式泄漏信息

在补丁中改变错误消息时要谨慎

复查错误路径

保持关闭的特性不变

内核模式错误

高级安全问题

句柄

符号链接

配额

序列化基元

缓冲区处理问题

IRP取消

在代码中添加关于安全的注释

利用操作系统

不要依赖用户去做正确的决定

安全地调用CreateProcess函数

不要给lpApplicationName传递NULL

用引号把lpCommandLine中可执行文件的路径括起来

不要创建共享的/可写入的代码段

正确使用假冒函数

不要把用户文件写入\ProgramFiles目录

不要把用户数据写入HKLM

不要以“完全控制”权限打开对象

对象创建错误

慎用CreateFile

安全地创建临时文件

Setup程序和EFS文件系统的问题

文件系统再解析点问题

客户瑞安全是自相矛盾的说法

范例成了模板

“吃掉你自己的狗食”

归功于用户

测定基于管理员SID的访问

允许使用长的密码

慎用_alloca

ATL转换宏

不要嵌入公司的名称

将字符串移至资源DLL

应用程序日志

从危险的C/C++迁移到托管代码

第24章 编写安全文档和错误消息

文档中的安全问题

关于文档的基础知识

通过文档缓解威胁

记录安全的最佳做法

错误消息中的安全问题

典型的安全消息

信息泄露问题

被迫同意

累进泄露

消息要具体些

最好不要提问

对安全消息进行可用性测试

审阅产品说明书时的注意事项

安全设置的可用性

本章小结

第V部分 附录

附录A 危险的API

附录B 我们所听到的荒谬借口

附录C 设计人员的安全措施和对清单

附录D 开发人员的安全措施和对清单

附录E 测试人员的安全措施和对清单

最后的想法

参考文献

索引