读软件开发安全之道:概念、设计与实施11安全地编程
https://img2024.cnblogs.com/blog/3076680/202408/3076680-20240827122320562-2105782004.png1. 安全地编程
1.1. 在一个完整的软件设计过程中,我们要在创建和审查时就将安全性放在心中,但这只是产物开发过程的开始,接下来是实现、测试、部署、运行、监控、维护,并最终在生命周期结束时将其淘汰
1.2. 开发人员不但必须老实地实现一个优良设计中明白的安全规定,还必须制止无意中通过有缺陷的代码引入额外的漏洞
1.3. 深思熟虑的设计师可以预测编程中遇到的题目,并就注重安全性的领域提供建议等
[*]1.3.1. 知道是什么让代码变得易受攻击,以及怎样让它更安全
1.4. 在理想情况下,在设计中应该指定主动的安全步伐,即为了掩护系统、资产和用户而构建的软件功能
[*]1.4.1. 注重开发中的安全性是为了制止软件轻易地掉入陷阱,比如组件和工具中的缺陷
2. 寻衅
2.1. 安全编码的寻衅主要在于制止引入缺陷,因为缺陷有大概成为可被利用的漏洞
[*]2.1.1. 制止以不安全的方式举行编码
2.2. 制作出能够真正运行的软件会带来更高的复杂性,而且需要在设计之外对细节举行填充,所有这些都不可制止地会带来安全风险
2.3. 完美并不是我们的目的,大多数会导致常见漏洞的编码失败模式都很好理解,而且不难改正
2.4. 恶意影响
[*]2.4.1. 在考虑安全编码时,需要考虑的一个重要因素是了解攻击者大概会怎样对正在运行的代码施加影响
[*]2.4.2. 不受信任的输入可以通过直接或间接两种方式对代码产生影响
[*]2.4.3. 有时不受信任的数据与代码的交互会触发错误,或者会触发具有副作用的功能
[*]2.4.4. 通过数据对代码产生影响的技术被称为污染
[*]2.4.5. 还有一些其他方法,可以在不存储数据的情况下,让输入数据对代码产生间接影响
[*]2.4.6. 在大型系统中,当你从攻击面开始考虑传递闭包(即全部路径的聚集)时,你可以体会到渗透到大量代码的潜力
[*]2.4.6.1. 能够通过多层举行扩展的能力很重要,因为这意味着攻击者可以访问比你预期更多的代码,从而使其能够控制代码所提供的功能
2.5. 漏洞是bug
[*]2.5.1. 大家都已经接受了所有软件都有bug这件事
[*]2.5.1.1. 破例也总是存在的:简单代码、可证实是正确的代码,以及运行在航空、医疗或其他关键设备上的高度工程化的软件
[*]2.5.2. 能够意识到bug的普遍性是走向安全编码的一个很好的起点
[*]2.5.3. 漏洞是对于攻击者来说有用的一部分软件bug,攻击者可以利用漏洞来造成伤害
[*]2.5.4. 几乎无法正确地将漏洞与其他bug区分开,因此一开始可以先辨认明显不是漏洞的bug,也就是完全无害的bug
[*]2.5.4.1. 网页布局未能按照设计工作,就是一个无害的bug
[*]2.5.4.2. 搞乱布局的bug也可以是有害的
>2.5.4.2.1. 遮盖了用户必须了解才能做出准确安全决策的重要信息,因此漏洞的发现是很复杂的
[*]2.5.5. 一般来说我们所有人都在编写大量的已知错误,更不消说未知错误了
[*]2.5.5.1. 如果还没有修复全部bug,请考虑那些已知的bug,标记其大概造成的漏洞,并举行修复
[*]2.5.5.2. 修复一个bug几乎总是比调查并证实它是无害的更容易
[*]2.5.6. 有些漏洞是难缠的bug,因为它们不符合任何模式,它们不知怎么躲过了测试,并最终被开释出来
[*]2.5.6.1. 代码在正常用途中往往会体现正常,只有在故意举行的攻击下才会显现出有害的举动
[*]2.5.7. 从过去的失败中吸取教训是很重要的,因为这些漏洞类别中的许多已经存在了几十年
2.6. 漏洞链
[*]2.6.1. 漏洞链的意思是看似无害的多个bug可以联合起来,并形成严重危害安全的bug
[*]2.6.1.1. bug加成效应
[*]2.6.2. “垫脚石”bug组合在一起,形成了可被攻击者利用的漏洞
[*]2.6.2.1. 在Pwn2Own黑客大赛中,有一个团队曾设法将6个bug连接在一起,以实现一次高难度的利用
[*]2.6.3. 辨认出bug是何时形成漏洞链的,通常非常具有寻衅性
[*]2.6.3.1. 很容易看出尽大概主动地修复bug是多么有远见
[*]2.6.3.2. 应该积极修复那些会引入脆弱性的bug,尤其是关键资产周围的bug
[*]2.6.3.3. 以为“会没事的”的观点就只是一个观点,而不是证据
[*]2.6.3.4. 以为“它永远不会发生”而将bug留在那里是有风险的
[*]2.6.3.5. 充其量只是一种暂时步伐,而不是一个好的最终分流决定
[*]2.6.4. 在实践中,通常很难说服其他人花时间针对那些看似模糊的假设来实施修复,尤其是当修复可疑bug需要大量工作时
[*]2.6.5. 很大概大多数大型系统中都充满了未被发现的漏洞链,从而导致我们的系统变脆弱
2.7. bug和熵
[*]2.7.1. 一些bug往往会以不可预测的方式对软件造成破坏,这使得我们很难分析它们的可利用性
[*]2.7.2. 由实验线程之间的意外交互所引起的bug往往是容易产生这种题目的一类bug,因为它们通常以各种方式出现,而且看起来似乎是随机的
[*]2.7.2.1. 内存破坏bug是这类bug中的另一种,因为堆栈的内容在不断变化
[*]2.7.3. 主动化降低了重复尝试的成本,直到他们的攻击成功为止
[*]2.7.4. 即使你无法清晰地找出明白的因果链,熵诱导出的bug也大概很危险,并值得修复
2.8. 警觉
[*]2.8.1. 有了意识,就可以应对困难的寻衅
[*]2.8.2. 注意力不会合很容易失败,即使事情并不困难
[*]2.8.3. 如果没有意识到潜在的安全隐患,并连续关注它,就很容易在不知不觉中掉入它的陷阱
[*]2.8.4. 为了能够交付安全的代码,一定要保持鉴戒并预测所有大概的输入和事件组合
[*]2.8.5. 警觉首先需要的是纪律,但随着练习的不断深入,当你知道要注意什么的时候,它就会成为一种习惯
[*]2.8.6. 每一次的修复都制止了未来有大概发生的攻击
3. 案例
3.1. 2014年,苹果公司为其大部分产物悄悄地发布了一系列关键安全补丁,而且出于“掩护我们的客户”的考虑,拒绝解释题目的缘故原由
[*]3.1.1. 一个明显的编辑失误造成的,这个失误破坏了安全掩护
[*]3.1.2. GotoFail
3.2. 教训
[*]3.2.1. 关键代码中的小错误会给安全性带来毁灭性影响
[*]3.2.2. 在预见到的用例中,易受攻击的代码仍能正常工作
[*]3.2.3. 对安全性测试来说,测试代码拒绝无效用例的能力,比测试代码在合法用例中的正常运行更为重要
[*]3.2.4. 代码审查非常重要,它能够找出无意间引入的bug
3.3. 对策
[*]3.3.1. 更好的测试
[*]3.3.1.1. 至少应该为每个if条件都设置一个测试用例,以确保所有必要的检查都有效
[*]3.3.2. 注意那些无法访问的代码
[*]3.3.2.1. 许多编译器都提供了选项以对此举行标记
[*]3.3.3. 让代码尽大概明白,比如多用圆括号和花括号,即使可以略去它们
[*]3.3.4. 使用诸如linter之类的源代码分析工具,可以提高代码质量,而且在此过程中大概会标记出一些潜在的漏洞,以提前举行修复
[*]3.3.5. 考虑使用ad hoc源代码过滤器来检测可疑模式
[*]3.3.6. 丈量并要求全面的测试覆盖率,尤其是对于安全关键代码
4. 编码漏洞
4.1. 新类别的bug是无穷无尽的,不要徒劳地试图编写一份涵盖所有潜在软件漏洞的完整列表
4.2. 原子性
[*]4.2.1. 将任务作为一个单一的步调并包管有效地完成
[*]4.2.2. 原子性是一个重要的防御武器,它可以用来预防大概会导致漏洞的意外情况
4.3. 时序攻击
[*]4.3.1. 时序攻击是一种旁路攻击,它会从操作实验的时间上推断出一些信息,以此间接地了解系统中本应是私密的一些状态
[*]4.3.2. 时间差有时可以提供一些暗示,也就是说会有少量的受掩护信息被泄漏,从而使攻击者受益
[*]4.3.3. Meltdown(熔断)和Spectre(幽灵)是针对现代处理器的时序攻击,它们运行在软件层面之下,但原理是相同的
[*]4.3.3.1. 利用了预测实验(speculative execution)的举动特性,即处理器会加速得到预计算效果,同时为了速度而暂时放松各种检查
[*]4.3.3.2. 攻击代码可以通过检查缓存的状态,来推测被取消的预测实验期间发生的事情
[*]4.3.3.3. 内存缓存技术加快了实验速度,但缓存不会直接披露给软件
[*]4.3.3.4. 代码可以判断特定内存位置的内容是否曾经存在于缓存中,这是通过丈量内存访问时间做出的判断,因为被缓存的内存处理速度快得多
[*]4.3.4. 当软件中存在一系列缓慢的操作(想想if…if…if…if…)时,软件的运行就会出现时间差
[*]4.3.4.1. 当我们对实验中的事件顺序有所了解时,就可以通过期间差来推断有价值的信息
[*]4.3.4.2. 当使用同一台机器上运行的代码来利用Meltdown和Spectre时,亚毫秒级的时间差都是可以被注意到的,而且这也是很重要的
[*]4.3.5. 最好的缓解步伐是将时间差缩小到可接受的水平,也就是难以察觉的水平
[*]4.3.6. 当软件中存在固有的时间差,而且这个时序旁路会导致严重的泄漏时,你可以用来缓解风险的做法就是人为引入时延,以模糊时序信号
4.4. 序列化
[*]4.4.1. 序列化是指将数据对象转换为字节流的通用技术
[*]4.4.2. 攻击者不但能够篡改关键数据值,而且通过构造无效的字节序列,甚至能够使反序列化后的代码实验有害的操作
[*]4.4.2.1. 需要信任输入的数据,才可以构建出相应的对象以完成相应的功能
[*]4.4.3. 只有对受信任的序列化数据实验反序列化才是安全的
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]