常见的xml实体解析导致的安全风险有哪些_软件源码安全攻防之道(下)

7d111cad-b61a-eb11-8da9-e4434bdf6706.png点击“蓝字”关注我们吧

上次咱们讲完了源码安全漏洞利用常见的几个姿势,本文接着来对对应的防御技术进行说明。改一个漏洞一般会比较简单,但是如何通过安全编程来避免一类某种类型的漏洞出现就会比较麻烦。其实,防御的原则相对比较好总结,主要就一个字“”:控输入、控过程、控输出。“控”字做好了,防御也就可以随之构建起来。

源码安全漏洞的防守之道●0 1  把好入口关,输入严校验

这里的输入是相对的,取决于你要关注的系统,取决于“安全防线”的位置(也称之为“安全边界”)。防线内部视为可信的系统,当做自己人;防线外部自然就是不可信的,当做外人。那么对于咱们要保护程序的来说,往往会有哪些类型的外部输入呢,下图给出了常见的一些外部输入类型:

81111cad-b61a-eb11-8da9-e4434bdf6706.png

对于外部的输入,你是否有预期逻辑限制,输入的全集是怎样的,合理输入的区间位于何处,需要妥当思考。举个例子,对于一个函数接口,如果需要处理一个外部输入的数据,那么往往会考虑到输入数据的长度、数据的数值范围和数据的字符集(如果是当成字符来处理的话)范围等等。

如果输入数据还需要做进一步处理(比如URL解码后,仍有危险字符构造注入),或者与预置数据拼接(比如拼接路径,使用“../”拼接跨越父级目录),那么需要进行再次确认,确保处理后的数据送到函数入参前是预期符合要求的参数。

另外前面也说到,“安全防线”的位置不是一成不变的,如果我们某台机器已证实被入侵,则来自它的输入也变为了不可信输入,其他机器也需要与之“划清界限”,对其输入再做校验。当前流行的“零信任安全”就假定了任何输入都不安全,接收输入前必须进行认证校验。输入校验是需要成本的,完全的“零信任”具有挑战,可以选择将力气着重花在主要矛盾的主要方面。

0 2  保护解析器,防数据变代码

前文也有提到,解析器往往是安全攻击的重灾区,解析器本身是为了提升固定格式或协议文件的解析效率,越复杂的解析器越可能出现较多的安全缺陷。为了保护解析器,需要知道我们用到了哪些解析器,是否是安全版本的解析器,使用解析器处理了哪种数据等等。

82111cad-b61a-eb11-8da9-e4434bdf6706.png

有些解析器是需要按照说明书进行合理配置的,而不是一上来就直接使用。安全配置解析器不意味着一定要限制解析器的功能,而是要避免开启开发者未预料到的功能。如果开发者对于要处理的数据协议本身都不了解,那很有可能会被攻击者钻了空子,比如xml协议的使用,有开发者可能对xml实体扩展的功能都不了解,而xml解析器如果开了实体扩展解析的功能,这样就极有可能导致xml解析接收到过量的实体扩展解析,损耗计算资源,导致拒绝服务。

85111cad-b61a-eb11-8da9-e4434bdf6706.png

常见的解析器安全配置和入参限制如下所示:

89111cad-b61a-eb11-8da9-e4434bdf6706.png

简而言之,三个要点:安全的版本,安全的配置,安全的入参。

0 3  控权限窗口,防权限滥用

权限管控是“控过程”中一块很重要的关注点,不同权限处理问题带来的影响也往往是不同的。现在用的比较普遍的权限访问控制是RBAC(即基于角色的访问控制),常见的越权攻击也分为水平越权(角色不变)和垂直越权(角色转变),如下图所示:

8c111cad-b61a-eb11-8da9-e4434bdf6706.png

鉴权的过程需要由服务器端完成,而非客户端,完成鉴权后,给对应用户一个“票据”,也就是会话Id,用户通过会话Id来进行对应权限的任务执行。针对单体的权限管控,也是从时间(权限的有效时间)与空间(权限的影响范围)角度来进行约束。

权限的使用原则应遵循最小化原则(空间+时间最小化),即“该用多少才用多少,该用多久采用多久”,而非“能用多少就用多少,能用多久就用多久”。

根用户权限和超级用户权限,需要进行约束,非系统级或弱系统级的服务尽量不用或少用。

90111cad-b61a-eb11-8da9-e4434bdf6706.png

0 4  数据安全生命周期防护,避免数据渗出

数据安全生命周期包括:安全采集,安全存储,安全传输,安全处理,安全交换和安全销毁。开发者需要对用到的数据,尤其是用户敏感数据和系统机密数据,保持相当高的敏感度,各阶段要进行对应的保护措施。常见的数据安全流转注意要点如下图所示:

92111cad-b61a-eb11-8da9-e4434bdf6706.png

数据的使用,也需要由“面向解决问题的数据获取”转为“面向数据保护的问题解决”,优先保护用户隐私和系统机密,然后再基于此给出问题解决之道,而非粗暴的拉取数据,图一时之快。数据加密技术的使用也是一个关注点,需要注意加密算法的安全性,密钥的安全保管,随机性因子的随机安全。

0 5  确定性与随机性:对开发者确定,对攻击者随机

前文有提到过攻击中“猜”的思想,其实从防御角度来说也就是解决确定与随机的问题。

我们程序中的异常处理,其实是一种确定性处理,确定的异常给出确定的处理。

98111cad-b61a-eb11-8da9-e4434bdf6706.png

对于异常,尽量不要宽泛捕获,这样容易导致忽略事先没有考虑到的情况,导致确定性缺失。确定性主要是对抗“天灾”,增强了开发者对于代码的把控,以便减少不确定性带来的未知风险。

而随机性的使用,主要是对抗“人祸”,干扰攻击者,增加攻击难度,像之前提到的ASLR技术就是通过随机干扰内存地址预测。终端隐私保护技术中,也有使用随机MAC地址摆脱网络探针跟踪的技术。

伪随机数生成器PRNG一般分为统计学PRNG和密码学PRNG。统计学PRNG通过统计来输出随机数,相对而言容易预测出来;而密码学PRNG一般会内置复杂的熵源,使生成的随机数相对来说更安全,不易预测。对于开发者来说,安全随机数API一般是可以查阅得到的,比如Java,使用SecureRandom替代Random就可获得安全性良好的随机数生成器。

0 6  层层防御,落地安全编码

实施有效的安全编码,可以减少很多安全缺陷,通过源码的层层安全防御,将风险也层层消减。及时修复代码中的最弱一环,提升整体软件的安全水位,避免攻击者从最弱一环层层突破开来。

9a111cad-b61a-eb11-8da9-e4434bdf6706.png

如果初期的开发团队还没有安全编码规范制定,可以先参考业界的优秀实践,整理定制一个适合自己团队的规范,引入已有安全库进行分析研究,落地到自己的软件产品之中。

9c111cad-b61a-eb11-8da9-e4434bdf6706.png

通过规范+流程+技术,增强开发人员整体的源码质量。规范的制定可能会引起部分编码高手的不满,认为降低了开发效率,觉得没有必要,缺乏安全意识。因此规范的培训和意识宣贯是必要的,这和部分老司机不经常打转向灯一样,不是因为不会,而是因为缺乏意识。

0 7  攻防互促,防患于未然

当开发人员认为做好了以上方面和安全编码以后,接下来就是需要进行“测验”了。先面临工具的考验,可以通过静态代码检查工具,模拟数据流(污染传递技术)和控制流把逻辑分支跑一遍,发现有哪些安全缺陷,如下图所示:

9d111cad-b61a-eb11-8da9-e4434bdf6706.png

第一次的整改往往伴随阵痛,也是对开发人员安全编码落地的一次检验。静态检查中的误报是难免的,部分人员甚至可以通过分析误报了解静态检查工具是如何运作的。排除掉误报,将真实缺陷问题逐一整改,再进行一轮检查确保整改没有引入新问题。

面临完工具的考验,接下来就是安全评估专家的考验了。内部安全评估专家一般通过两种方式进行安全评估。

第一种是“硬核派”,正向而行,直接走读代码和不断调试发现缺陷,需要对目标软件系统有足够了解,且对安全编码规范了如指掌;第二种是“讨巧派”,逆向溯源,通过检查或监控关键部位,分析系统输出看问题是否可利用,有时也会通过Fuzz等技术帮他们找出异常点。

9e111cad-b61a-eb11-8da9-e4434bdf6706.png

内部的安全评估可以发挥安全评估人员(白帽子)的专长,发掘更深层次的安全问题,同时也可以对开发进行赋能,将部分对安全产生兴趣的同学也纳入进来作为种子成员。不断的内部攻防可以有效提升产品安全质量,是技术,更是艺术。

攻防之道总结

攻防技术互促,知点防面是很重要的。开发者对代码开发是最了解的,但是也不能忽视安全意识。有的技巧点并不是不知道,而是容易忽略掉,遵守安全编码,是可以有效降低软件的缺陷密度的。

a0111cad-b61a-eb11-8da9-e4434bdf6706.png

知己知彼,百战不殆。笔者能力有限,如文章中有讹误之处,欢迎大家指正。

最后给大家推荐2个链接,前者为攻,后者为防,供大家进一步了解。

  • ATT&CK框架:https://attack.mitre.org

  • CWE:https://cwe.mitre.org

a1111cad-b61a-eb11-8da9-e4434bdf6706.gif

a3111cad-b61a-eb11-8da9-e4434bdf6706.gif

●如何用lint扫出不安全代码

●如何用OLLVM来保护你的关键代码

●Android native内存检测工具介绍

●软件源码安全攻防之道(中)

a4111cad-b61a-eb11-8da9-e4434bdf6706.gif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 介绍 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。 2)SAX SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。 选择DOM还是选择SAX? 对于需要自己编写代码来处理XML文档的开发人员来说, 选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX采用的事件模型。 DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。 SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。 3)JDOM http://www.jdom.org JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。 JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。 JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有用的,并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习DOM或JDOM接口都更有意义的工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值