安全简报

适用于 TFS 2010 的 MSF-Agile+SDL 过程模板

Bryan Sullivan

本杂志的任何忠实读者都会熟悉 Microsoft Team Foundation Server (TFS) 和开发团队使用它可获得的工作效率优势。(如果您不熟悉 TFS,请从 Visual Studio 2005 指导教程查看 Chris Menegay 的文章。虽然其中含有旧版本内容,但为可在 TFS 中利用的各种功能提供了有用的概述。)

如果您自己使用 TFS,则也可能熟悉随 TFS 一起提供的 Microsoft Solutions Framework (MSF) for Agile Software Development 过程模板,更普遍的叫法是 MSF-Agile。本月专栏的主题是新 MSF-Agile 与安全开发生命周期 (SDL) 过程模板。MSF-Agile+SDL 基于 MSF-Agile 模板构建,向开发流程添加 SDL 安全和隐私功能。

您可以从 microsoft.com/sdl 下载用于 Visual Studio Team System 2008 或 2010 的 MSF-Agile+SDL 模板。但是在下载之前,您可能需要了解其中内置了哪些功能。下面我们就开始。

SDL 任务

SDL 的核心是其安全要求和建议 – 即开发团队在整个开发生命周期中必须执行的活动,以便确保最终产品具有较好的安全性和隐私性。这些要求包括策略活动,例如创建安全事件响应计划,以及技术活动,例如威胁建模和执行静态漏洞分析。所有这些活动在 MSF-Agile+SDL 模板中均表示为 SDL 任务工作项。

SDL 任务与表示功能任务的标准工作项之间的最大区别,可能在于项目团队成员不打算自己直接创建 SDL 任务。首次创建团队项目时,会自动创建一些 SDL 任务。这些任务是相对简单明了的一次性安全任务,例如确定将充当主要安全联系人的团队成员。其他 SDL 任务由过程模板自动创建来响应用户操作。(更具体地说,它们是由部署到 TFS 应用程序层的 SDL-Agile 控制器 Web 服务自动创建的。)

无论用户何时向项目添加新的迭代,模板都会向项目添加新的 SDL 任务,用于表示该迭代期间要执行的安全任务。威胁建模就是每迭代 SDL 任务的一个较好的例子:团队必须评估在迭代过程中进行的更改,从而确定潜在的新威胁和抑制措施。

最后,无论用户何时将新的 Visual Studio 项目或 Web 站点签入到团队源代码控制存储库,模板都会添加 SDL 任务来反映必须专门为该项目执行的安全工作。例如,无论何时添加新的 C 或 C++ 项目,都会创建 SDL 任务以确保使用缓冲区溢出防御编译器和链接器设置,例如地址空间布局随机化对应的 /dynamic­base 标记和缓冲区安全检查对应的 /gs 标记。

模板已足够完善,能够识别本机 C/C++ 项目与 Microsoft .NET Framework 项目之间的区别,不会添加无效要求。/dynamicbase 和 /gs 标记对于 C# 代码无意义,不会为 C# 项目创建这些 SDL 任务。C# 项目将获得特定于 .NET 的安全任务,例如复查 AllowPartiallyTrustedCallersAttribute 的任何用途。同样,模板也可以从 Web 站点和 Web 服务区分客户端/服务器和独立桌面应用程序,并因此添加相应的 SDL 任务集。

SDL 任务工作流和异常

SDL 任务的状态和原因工作流转换与功能任务的工作流转换也不相同。可按以下若干不同的原因将任务标记为已关闭:已完成、已从项目中剪掉、延迟到后期迭代,甚至已废弃,以及不再与项目相关。这些原因中,只有“已完成”适用于 SDL 任务。

遵循 SDL 的团队无法从其项目中削减掉安全和隐私要求。功能性要求可因技术原因或业务原因在项目内外进行合理取舍,但是安全要求必须保持较高标准。永远跳过 SDL 任务并不是不可能,但是要实现此操作,必须遵循更高级的过程。

无论什么原因,如果团队无法完成必需的 SDL 任务,则必须向其安全顾问申请任务异常。团队或团队管理层在项目开始时选择团队的安全顾问。此类人员应该对应用程序安全和隐私有丰富经验,最好不直接参与项目,他不应是项目开发人员、项目经理或测试人员之一。

在 Microsoft,有一个集中式安全顾问组,他们在高信度计算安全性部门工作。这些安全顾问直接与各个产品团队配合工作。如果您的组织具有相应资源来创建专门的安全顾问库,将是比较好的情况。如果没有,最好选择在安全性方面具有最资深背景的人员。

团队的安全顾问负责批准或拒绝 SDL 任务的任何异常请求。团队通过将 SDL 任务状态设置为“已请求异常”,然后填写“理由”、“解决方案计划”和“解决方案时间范围”字段来创建异常请求。此外,每个 SDL 任务还有一个只读的“异常评级”字段,表示未完成要求的固有主观安全风险,范围从 4(最低风险)到 1(严重;最高风险)。安全顾问权衡团队对异常评级的理由说明,然后要么关闭“原因”是“已批准”的 SDL 任务,要么重新激活“原因”是“已拒绝”的 SDL 任务。

但是,即使已批准请求,大多数异常也不会永远持续存在。这便是“解决方案时间范围”字段发挥作用的地方。团队通常要求异常出现所设置的迭代次数,通常只是一次迭代,但是有时多达三次。超过指定的迭代次数后,过程模板将使异常过期,并重新激活 SDL 任务。

安全错误

在确保满足安全和隐私要求后,SDL 的下一个最重要功能是确保产品发货时不含已知的安全错误。将安全错误与功能错误分开跟踪,对确保产品的安全运行状况至关重要。

与 SDL 任务不同,MSF-Agile+SDL 模板不会添加另一个 SDL 错误工作项类型来区分安全错误与功能错误。该模板向现有错误工作项类型添加“安全原因”和“安全影响”字段。无论团队成员何时归档新错误,如果错误是没有安全影响的严格功能错误,查找器只会让这些字段保持其默认值“不是安全性错误”。但是,如果错误确实表示潜在的安全漏洞,查找器会将“安全原因”设置为以下值之一:

  • 算术运算错误
  • 缓冲区向上溢出/向下溢出
  • 跨站点脚本
  • 加密缺陷
  • 目录遍历
  • 不正确/无错误消息
  • 不正确/无路径名称规范化
  • 无效机密隐藏
  • 争用条件
  • SQL/脚本注入
  • 无限资源消耗(拒绝服务)
  • 弱身份验证
  • 弱身份验证/不适当权限或 ACL
  • 其他

查找器还将“安全影响”设置为以下 STRIDE 值之一:

  • 假冒
  • 篡改
  • 否认
  • 信息泄露
  • 拒绝服务
  • 提升权限

最后,查找器也可以选择为错误设置范围值。简而言之,范围定义有关错误的一些附加主观信息,这些信息随后用于确定严重性。范围的允许值因所选的安全影响而异。例如,如果您为“安全影响”选择“特权提升”,“范围”的可能选项包括:

  • (客户端)远程用户能够执行任意代码或获得比预期更多的特权。
  • (客户端)远程用户能够通过大量的用户操作执行任意代码。
  • (客户端)本地的低特权用户可以将自己提升为其他用户、管理员或本地系统。
  • (服务器)远程匿名用户能够执行任意代码或获得比预期更多的特权。
  • (服务器)通过身份验证的远程用户能够执行任意代码或获得比预期更多的特权。
  • (服务器)通过身份验证的本地用户能够执行任意代码或获得比预期更多的特权。

您可以看到特权提升漏洞的严重性轴(即,使某一特权提升比其他特权提升更糟的特性),处理各种条件,例如攻击的站点(客户端或服务器)和攻击者的身份验证级别(匿名或通过身份验证)。但是,如果您选择其他安全影响,例如“拒绝服务”,范围选项将发生变化,以反映该特殊影响的严重性轴:

  • (客户端)要求重新安装系统和/或组件的拒绝服务
  • (客户端)要求重新启动或导致蓝屏/错误检查的拒绝服务
  • (客户端)要求重新启动应用程序的拒绝服务
  • (服务器)具有少量数据的匿名用户的拒绝服务
  • (服务器)没有在默认/常见安装中扩大的匿名用户的拒绝服务
  • (服务器)要求重新启动或重新安装系统的已通过身份验证的用户的拒绝服务
  • (服务器)默认/常见安装中已通过身份验证的用户的拒绝服务

为“安全原因”、“安全影响”和“范围”都输入值后,模板将使用这些数据计算错误的最低严重性。用户可以选择设置高于最低评级的实际错误严重性,例如,将错误设置为“1–严重”而不是“2–高”,但是从不进行反方向设置。这似乎有点过于严格,但是这样可避免尝试将错误严重性降级来满足发货日期或突击发布截止日期。

如果您要详细了解有关设置更客观的错误评级方法来会审错误的理由说明,请阅读 2010 年 3 月“安全简报”专栏,“向 Microsoft Team Foundation Server 2010 中添加安全错误评级”(msdn.microsoft.com/magazine/ee336031)。我在那篇文章中详细介绍了向 TFS 添加错误评级的过程,该过程已经内置到 MSF-Agile+SDL 模板中。

最后,错误工作项中还有一个可选字段。您可以使用“来源”字段指定最初发现错误(如果有)的自动安全工具的名称,如果用户通过手动代码检查或测试发现错误,您也可以使该字段保留其默认值“用户”。

随着时间的推移,您将收集到足够的数据来确定您的哪些测试工具可提供最大回报。为了更容易地作出该决定,MSF-Agile+SDL 模板包括一个名为“Bugs by Origin”的 Excel 报告,该报告显示了一个按“来源”字段细分的漏洞评级图表。

您可以根据严重性、安全原因或安全影响自定义此报告来筛选数据。如果您要了解哪些工具可最有效地查找交叉站点脚本漏洞,或者哪些工具找到了严重性最高的特权提升错误,很容易做到。

错误工作流

正如您无法延迟 SDL 任务一样,您无法延迟具有安全隐患的任何错误(即“安全影响”设置为“不是安全性错误”以外其他值的任何错误)。要延迟修复严重性为“3 – 中等”或更高的任何安全错误,团队必须申请异常。

这一过程与 SDL 任务的异常申请过程完全相同:团队成员将状态设置为“已请求异常”,为“理由”、“异常解决方案”和“异常时间范围”字段输入详细信息。然后,团队的安全顾问检查异常请求,要么批准(将状态设置为 “由于‘原因’为‘已批准’而关闭”),要么拒绝(将状态设置为“由于‘原因’为‘已拒绝’而激活”)。

安全查询和安全仪表盘

此外,为了简化以下过程,MSF-Agile+SDL 模板还包括若干新团队查询。这些新查询位于团队资源管理器中的 Security Queries 文件夹下,包括:

  • 活动安全错误
  • 我的安全错误
  • 已解决的安全错误
  • 打开 SDL 任务
  • 我的 SDL 任务
  • 打开异常(包括任务和错误,对安全顾问尤其有用)
  • 批准的异常
  • 安全退出标准

这些查询中的大多数不言自明,但是“安全退出标准”查询需要多费一些口舌。为了满足 SDL 对给定迭代的承诺,团队必须完成所有以下活动:

  • 该迭代的所有每个突击发布的重复性 SDL 任务要求必须完整,或者具有由团队安全顾问批准的异常
  • 不得有过期的一次性或存储桶 SDL 任务要求
  • 具有严重性为“3 – 中等”或更高的安全隐患的所有错误均必须关闭,或者具有由团队安全顾问批准的异常

在此上下文中提到的“每个突击发布”、“一次性”和“存储桶”等术语是指对各个要求进行组织的 SDL-Agile 概念,其基础是完成这些活动必须按照的频率。每个突击发布要求是重复性要求,必须在每次迭代中完成。一次性要求是非重复性要求,只需要完成一次。存储桶要求是重复性要求,但是只需要每六个月完成一次。

对此分类系统的详细讨论已超出本文范围;但是如果您要详细了解该系统,请阅读 2008 年 11 月这一期的《MSDN 杂志》文章“Agile SDL:简化敏捷开发的安全实践”。

“安全退出标准”查询的意图是为团队成员提供一种简单的方式来检查他们为了完成其 SDL 承诺还要做多少工作。如果您在创建 MSF-Agile+SDL 团队项目时为该项目配置 SharePoint 站点(该操作通常自动进行),您还会在团队项目的安全仪表盘上看到“安全退出标准”查询结果。

新的安全仪表盘仅适用于 MSF-Agile+SDL 项目(请参阅图 1)。默认情况下,该仪表盘包括“安全退出标准”、“打开 SDL 任务”、“打开异常”和“安全错误”查询,但是如果您喜欢,也可以自定义这些查询。此外,还可以将安全仪表盘设置为所有 MSF-Agile+SDL 项目的默认项目门户页面,但是如果您要更改到其他默认仪表盘,只需打开仪表盘文档库,选择您要使用的仪表盘,然后选择“设置为默认页面”选项即可。

图 1 MSF-Agile+SDL 安全仪表盘

“标准”、“打开 SDL 任务”、“打开异常”和“安全错误”查询,但是如果您喜欢,也可以自定义这些查询。此外,还可以将安全仪表盘设置为所有 MSF-Agile+SDL 项目的默认项目门户页面,但是如果您要更改到其他默认仪表盘,只需打开仪表盘文档库,选择您要使用的仪表盘,然后选择“设置为默认页面”选项即可。

签入策略

MSF-Agile+SDL 过程模板的最后一个功能是 SDL 签入策略集。这些策略有助于防止开发人员签入违反某些 SDL 要求并因此可能导致安全漏洞的代码。可用的 SDL 签入策略如图 2 所示。

图 2 MSF-Agile+SDL 签入策略

SDL 签入策略 说明
SDL 禁止的API 确保处理警告 C4996(使用已弃用的函数)的编译器选项将被视为错误。由于可能导致缓冲区溢出的大多数运行时库函数(例如 strcpy、strncpy 和 gets)已被弃用,以便支持更安全的替代函数(分别为 strcpy_s、strncpy_s 和 gets_s),使用此签入策略可以大大增强应用程序对缓冲区溢出攻击的抵抗力。
SDL 缓冲区安全性检查 确保已启用编译器选项“启用缓冲区安全性检查”(/GS)。此选项重新组织已编译程序的堆栈,以包括安全性 Cookie 或 Canary 值,这将大大提高攻击者为任意堆栈溢出漏洞编写可靠攻击代码的难度。
SDL DEP 和ASLR 确保已启用链接器选项“数据执行保护”(/NXCOMPAT) 和“随机化基址”(/DYNAMICBASE)。这些选项随机分配应用程序将加载到内存中的地址,有助于防止执行内存中预期以数据形式分配的代码。尤其是在组合使用时,这两个选项是对缓冲区溢出攻击强有力的深层防御措施。
SDL 安全异常处理程序 确保已启用链接器选项 /SAFESEH。此选项帮助防止攻击者定义恶意的异常处理程序,这种程序可能会导致危害系统。在链接时,/SAFESEH 创建一个合法异常处理程序表,并且不允许其他异常处理程序运行。
SDL 未初始化变量 确保编译器警告级别是在级别 4 (/W4) 这一最严级别设置的。如果使用此选项,将在可能使用变量而未进行初始化的代码处设置标记,这可能导致潜在攻击。

启用任何或所有 SDL 签入策略很简单。在团队资源管理器中,右键单击一个团队项目,然后从上下文菜单中选择“源代码控制”选项。选择“签入策略”选项卡,然后添加您想要增强的 SDL 策略(请参阅图 3)。务必注意,签入策略增强是在客户端计算机上而不是在 TFS 服务器上执行的,因此您需要在每个开发人员的计算机上安装 SDL 签入策略。

图 3 添加签入策略

总结

要使任何安全开发方法有效,其必须易于自动操作和管理。MSF-Agile+SDL 过程模板对这两种要求都有很大帮助。如果您已在使用 TFS 附带的 MSF-Agile 过程模板,则应已了解如何使用 MSF-Agile+SDL 模板,该模板是您已经熟悉的 MSF-Agile 模板的一个严格超集。请从 microsoft.com/sdl 下载,然后开始创建如今更安全和隐私意识更强的产品。

Bryan Sullivan* 是 Microsoft 安全开发生命周期团队的一名安全项目经理,专门负责 Web 应用程序和 .NET 的安全问题。他是“Ajax Security”(Addison-Wesley,2007)一书的作者。*

*衷心感谢以下技术专家对本文进行了审阅:*Michael Howard