写点什么

敏捷项目中的安全需求管理

2012 年 8 月 04 日

在软件开发初期处理安全需求是防止安全问题最经济的方式。大多数安全需求都属于非功能性需求(Non-Functional Requirements ,NFRs)。很多从业者发现,在敏捷项目中处理安全和其他 NFR 非常具有挑战性。原因有二:

  1. 匹配 NFR 和特性驱动的用户故事需要付出很大努力;
  2. 安全控制常因缺少可见度而被忽视。敏捷过程容易让团队不自觉地侧重于那些可以直观改善客户体验 的新功能开发或缺陷修复。

在本文中,我们会探讨以上两个问题。

在用户故事中处理 NFR

敏捷专家们提出过一些方法,用以定义用户故事驱动的开发过程中的 NFR。Mike Cohn 在他的文章中讨论了评论者们提出的一些有趣的建议。Scott Ambler 就该主题写了一系列文章,旨在证明并非所有的 NFR 都可以独立存在于用户故事中。而 Dean Leffingwell 可以说在这方面做了最深入的研究,他在自己的著作《敏捷软件需求》中花了整整一章探讨该主题。这些专家中大部分人都认为,NFR 大致可以分成两类:

  1. 非功能性用户故事:以用户故事的形式展现的可测试功能块。这些用户故事中的参与者(Actor)可能是内部 IT 人员。例如:“作为安全分析师,我希望系统能抑制不成功的身份认证尝试,这样应用程序在面对暴力破解时不至于太过脆弱”。
  2. 约束:这是个跨领域的问题,常常涉及多个用户故事。我们可以将它看作是对所有相关开发工作收取“课税”。例如:开发 Web 应用时,要求所有开发者对 Http 表单中的字段进行数据校验即为一种约束。

处理第一类 NFR 很简单:创建一系列的 NFR 用户故事,将它们加入某种工作序列,例如 Product Backlog。

NFR 约束的挑战:

然而处理第二类 NFR 则困难很多。敏捷专家们对此提出过一些解决办法,包括:

  • 在特定的用户故事中添加恰当的约束作为验收标准
  • 在某个中央知识库——例如,贴在墙上或者发表在 wiki 上的一份文件——中维护包含所有约束的列表。

但无论哪个方法都无法解决的问题是,如何针对特定的用户故事选择适用的约束。而且,使用 SD Elements 进行安全需求匹配的经验表明,要将这些技术限定在一定范围之内很困难。下面这个列表是标准 Web 应用需要面对的安全约束中的一部分,我们以此为例:

该列表列举的可能只是程序员在实现用户故事时需要考虑的安全约束中的一小部分。若将需要遵循的法规标准——诸如支付卡行业数据安全标准 (PCI DSS) 之类——考虑在内,约束还要增加不少。如果你开始添加其他 NFR 约束,例如可访问性,约束列表会快速增长,转眼间就会超过程序员的承受范围。一旦列表变得臃肿,我们的经验是,程序员往往会将它全部忽略,仅根据自己的记忆来应用 NFR 约束。而在很多不断专业化的领域——例如应用安全——NFR 的数量不断增长,这给程序员的记忆力造成了沉重的认知负担。因此,如何使用静态分析技术侦测代码中违背 NFR 约束之处就成了关注重点。研究表明,静态分析可以侦测出的可预防缺陷最多不超过总数的 40%,也就是说仍有大量的约束漏网,包括特定领域的安全控制,更别说在缺乏定制的情况下辨别静态分析产生的“假阳性”结果也不是那么简单。

应对 NFR 约束的挑战

为了解决 NFR 约束过多的问题,我们需要做到以下四点:

  • 按优先级排序:与用户故事和缺陷一样,NFR 约束也应拥有不同的优先级,例如:相较于避开 HTML 中的不可信数据以防止持续的跨站脚本攻击,对 HTTP 响应头中的不可信数据进行编码或校验以防止 HTTP 响应拆分攻击就不那么重要。因此我们假定程序员通常没有足够的时间处理所有约束,然后我们提供一种机制为如何定义约束的相对优先级提供建议。之所以说“建议”,是因为优先级有可能随着具体情况的变化而变化,程序员需要自己作出判断——对于他们的特定代码,哪种相对优先级是适用的。你可以选用简单的优先级设置,如“高、中、低”,也可以使用数字范围,如 1-10。
  • 过滤:使用简单的标准常常就可以为特定的用户故事移除大量的 NFR 约束。举例来说,假如你正在实现的用户故事与表现层无关,那么就可以安全地忽略大量表现层相关的约束。使用标签系统或者简单的 Excel 过滤器,就可以为特定的用户故事削减约束数量。以下是一些 Web 应用相关的安全性约束过滤器的范例:
    • 用户故事是否涉及用户输入;
    • 用户故事是否涉及保密数据,如密码、信用卡信息以及非公开的财务数据;
    • 用户故事是否返回一个全新或修正过的用户输出,例如一个网页;
    • 用户故事是否与数据库进行交互;
    • 用户故事是否会暴露或使用来自 RESTful 或 SOAP API 调用的数据;
    • 用户故事是否会访问受保护的数据(例如,不是所有用户都能查看或修改的数据)。
  • 情境(Context):程序员在写代码或定义任务单(tickets)/ 用户故事的时候更容易记起并应用约束。理想情况下,如果把约束列表内嵌入 IDE 或任务单系统,那么程序员就可以在编码时获取相关的约束。既然现在很多 IDE 都支持内嵌的 Web 浏览器,那么使用轻量级的网站或者 SharePoint 站点就可以实现这个目标。
  • 框架:框架可以大幅减少约束产生的“税收”。例如,像 Django 这样的框架自带了 CSRF 防护,这意味着程序员可以安全地忽略该约束,除非他们主动绕过这个内建的功能。根据我们的经验,多数大型的应用软件都会采用某种形式的定制框架,这些框架可以无缝处理最高优先级的约束。虽然这样的框架定制可能需要较高的先期投入,但如果你将约束看成一种基于用户故事的“税收”,那么减少约束数量就相当于永久性的降低了“税率”。

验证

虽然主动处理 NFR 很重要,但仍有必要进行验证。如果你有手动代码审查(Code Review)的经验,就可以检查用户故事中作为验收标准出现的 NFR。然而,如果仅使用手动代码审查,很多约束的验证将是非常棘手或者繁重的。静态分析工具则可以自动检查编码标准的遵守情况,其中一些产品特别关注安全方面。将你的静态分析工具与持续集成过程整合在一起,可以帮助你始终遵守编码标准。但也务必注意,不要一味依赖于代码审查。防范特定领域缺陷——如 HTTP 参数篡改——的 NFR 要求对背后的业务领域有深刻的理解。将手动验证与针对特定攻击的自动测试结合起来,可以帮助我们建立一套对于特定领域缺陷拥有更强抵抗力的系统。

可见度

难以将安全需求集成进敏捷项目的另一方面原因是安全需求通常缺乏可见度。面向客户的会议,如 Scrum 的 Sprint评审会议,容易使开发人员产生一种固有的倾向,即实现用户故事或修复缺陷时倾向于那些能直接改善用户体验的故事或缺陷。一部分非功能属性,例如易用性和性能,对于系统的使用体验有具体的影响,因此也比较容易向客户展示。而另外一些——如安全性——却很难在 Sprint 评审会议上给客户留下很好的印象。实际上,某些安全特性,如账号封锁(Account Lockout),可能给客户体验带来相当负面的影响。大多数安全特性对系统的影响,普通用户很难察觉。因此,安全性 NFR 是不可见的,它们必须和可见度更好的特性竞争,以夺得宝贵的开发周期。在软件开发初期,准确的说在程序员应该构建安全特性的时候,处理这些“隐形”需求的机会成本会特别高。

让安全特性可见

对于敏捷团队来说,没有“银弹”能让安全需求在开发伊始就拥有最高优先级。但有一些方法可以让安全 NFR 对客户和 / 或 PO 可见。

  • 图形化安全用户故事:如果你在应用程序安全方面足够专业,就可以针对已知的安全弱点创建一套全面的安全控制。然后将它们与 NFR 用户故事匹配起来,并绘制简单的图形,用以说明系统中已实现的和未实现的安全用户故事数量。这个图可以放在大型可视图表中。

    图 1:安全用户故事图
    当然,这个图没必要局限于安全用户故事,你可以将其他重要的 NFR 囊括进来。实际上,你可以使用故事点(Story Point)取代用户故事数量,从而更准确的反映工作量。另外,你有可能希望图中只记录那些针对高风险安全问题的、拥有最高优先级的用户故事或控制。每完成一个故事,“已完成”数量都会增加,客户也会籍由此图直观地了解项目的进度。
  • 展示可利用性(exploitability):没有什么比可利用性展示更能让人们理解一个安全漏洞的各个方面了。这是安全性渗透测试和漏洞评估的主要区别。你可以展示在上一版本的应用中如何成功地利用了漏洞,而在新的版本中却没办法这么做了。然后你可以从对业务和/或客户影响的角度解释漏洞的方方面面。这非常有利于解释为什么在安全控制上花的时间是合理的。

结论

主动处理 NFR,特别是安全特性,在敏捷环境中非常重要。不少专家对于如何处理此类需求——特别是当它们与创建用户故事相关时——给出了建议。全面地处理约束是个相当大的挑战。记住本文讨论的提议,你可以极大地增加维护一系列约束的价值。即使不能完全做到以上所提的四点内容以改善对约束的管理,但从长远来看,任何一点改进都能带来很高的回报。进行验证能保证团队始终遵守 NFR。最后,提高安全特性的可见度,可以让你证明用在 NFR 上的时间是合理的,就算它们对系统的改善不能反映到用户体验上。

关于作者

****Rohit Sethi( @rksethi on Twitter)是一位安全领域的专家,他致力于将安全控制构建到整个软件开发生命周期中(SDLC)。他曾帮助一些对安全相当敏感的企业改善软件安全性,涉及的行业包括金融服务、软件、电子商务、保健以及电信等。Rohit 创建并讲授针对 Secure J2EE 开发的 SANS 课程。他曾在以下机构讲学:FS-ISAC、RSA、OWASP、安全开发会议(Secure Development Conference)、Shmoocon、CSI National、SecTor、Infosecurity、CFI-CIRT 等等。他曾在 InfoQ、Dr. Dobb’s Journal、TechTarget、Security Focus 以及 Web Application Security Consortium (WASC) 上发表过文章,上过 Fox News Live,还曾被 ITWorldCanada 和 Computer World 以应用安全专家的身份引用过。另外,他还创建了 OWASP Design Patterns Security Analysis 项目。

查看英文原文: Managing Security Requirements in Agile Projects

2012 年 8 月 04 日 00:002886

评论

发布
暂无评论
发现更多内容

【译】并不存在的普通用户(面向极端用户的设计)

Yukun

设计思维 可用性

redis数据结构介绍四-第四部分 压缩表

Nick

redis 源码 数据结构 源码分析 算法

RocketMQ - 如何实现顺序消息

Java收录阁

RocketMQ

使用 Python 分析 Google Calender 日程

Roc

Python 总结 日历

学慢点儿,想深点儿

熊斌

学习

Yii2.0 RESTful API 之速率限制

Middleware

php RESTful Yii2

redis数据结构介绍五-第五部分 对象

Nick

redis 源码 数据结构 源码分析 算法

ARTS-weekly-31

落英坠露

ARTS 打卡计划

微信推文无缝滚动是这样炼成的

喵喵侠

微信 前端开发 微信公众号 微信推文 图文混排

教师节H5案例制作思路分享

喵喵侠

前端开发 H5游戏

简述 HTTP 缓存相关的首部及其行为

黄耗子皮

缓存 HTTP

技术工作的一二三之内功

拖地先生

个人成长

平台化服务的基石:用户认证模型设计

孤岛旭日

企业架构 模型 用户权限

RocketMQ broker.properties

李绍俊

RocketMQ

最长回文算法(马拉车算法)分析

Gadzan

Java 算法 LeetCode

一周信创舆情观察(5.18~5.24)

统小信uos

基础软件 操作系统

JUC整理笔记三之测试工具jcstress

JFound

Java

技术工作的一二三之快餐

拖地先生

项目管理 软件开发 技术管理 软件开发流程

[JVM] String#intern 面试必会

猴哥一一 cium

Java JVM string pool string Java 25 周年

一个前端的 Windows10 开发环境

Gadzan

前端开发 windows Windows Terminal 环境安装 开发工具

企业也有中年危机?探讨数字化与永续经营

fino星君

数字化转型 小程序生态

Kubernetes in action 笔记

FeiLong

Kubernetes 容器

ansible-playbook中when结合tags使用,实现变量控制执行

唯爱

使用 Python 和 SudachiPy 进行日语分词

Roc

Python 日语 分词

阅读对写作的好处

七镜花园-董一凡

写作

redis数据结构介绍六 快表

Nick

redis 源码 数据结构 源码分析 算法

介绍一下自研开源NLP工具库---MYNLP

陈吉米

自然语言处理 中文分词 mynlp nlp

KubeFATE 部署多集群联邦学习平台 FATE

亨利笔记

学习 Kubernetes FATE KUBEFATE

技术工作的一二三之价值观方法论

拖地先生

个人成长 方法论

Java 异步编程:从 Future 到 Loom

理帆

Java 并发编程 kotlin Netty

Git数据传输模型及常用命令整理

王坤祥

git git flow

敏捷项目中的安全需求管理-InfoQ