Web开发框架安全杂谈
EMail: wofeiwo#80sec.com
Site: http://www.80sec.com
Date: 2011-03-14
From: http://www.80sec.com/
[ 目录 ]
0×00 起
0×01 承
0×02 转
0×03 合
0×00起
最近框架漏洞频发,struts任意代码执行、Django csrf token防御绕过、Cakephp代码执行等等各大语言编程框架都相继暴出高危漏洞,这说明对于编程框架的安全问题已经逐渐走入安全工作者的视线。
Web开发框架就相当于web应用程序的操作系统,他决定了一个应用程序的模型结构和编程风格。框架上出了漏洞,就如同当年一个rpc远程EXP就走遍全世界windows的时代。
然而挖掘深层原因,从应用的模型和架构上考虑问题,其实这些框架漏洞都不只是一种偶然,而是一种必然。正是因为框架的模型结构,正因为他们的这种编程风格,才极大的增加了漏洞产生的可能性。
0×01承
现代编程框架的几个大特点:
1、将程序代码分为不同层次,业务开发、前端开发、数据库开发人员各司其职,框架根据需要组装代码、调度执行
2、统一化自动化逻辑处理
3、常见功能的代码库封装并高度重用
4、脚手架功能,常见代码组件自动组装生成。如默认用户系统、默认后台。
然而就是以上几点广受好评的功能导致了安全薄弱点的产生。
1、代码调度
让我们来先回顾一下WEB应用框架所最常见的MVC模型。
用户发送一个HTTP请求过来,框架的入口点(一般是route,路由)分析用户请求的url。然后依照url中蕴含的信息分析出用户所要访问的
controller、action,从而分发给相应的controller文件中的action函数,执行之;随后controller再将model
中的数据结合用户输入数据依照view层中的代码逻辑填充模板,最后view、controller执行完毕,返回用户最后的HTML。
整个生命周期是这样的:
用户请求url->route分发->controller接管处理用户输入及业务逻辑->view层代码执行->controller返回展现结果
从上面的流程发现了什么?
MVC模型就是一个将程序员分散在M、C、V中的代码寻找并整合在一起执行的过程。那这必然就要牵涉到一个代码调度执行的问题。这里route就是一个非
常明显的例子。一个框架这么多代码文件,route每一次调用controller,都需要根据用户输入的url进行匹配并执行用户指定的函数。这里就是
一个薄弱点,一个必然绕不过去的问题。
对应到现实的例子,一个非常明显的例子就是:struts2框架的动态方法调用(DMI)
当你访问www.test.com/a!test.action时,struts会根据你的url帮你映射到名为a的controller中名为test
的Action方法。而通过修改test的值,我们可以访问a这个类中的所有方法。如果恰好这个方法中含有敏感的信息,攻击者就获得了一切。结合其他技
巧,攻击者能够做到的更多。但这就是框架的功能,框架总是要依靠URL中的内容去匹配执行程序代码。
那么对于PHP的框架呢?仔细想一下,如果PHP需要做分散在不同文件中的代码调度执行,唯一能够实现的方式就是使用 require/include函数包含文件。文件名来源于哪里?来源于用户输入的URL。实际上目前市面上的大部分PHP框架也都是这么实现 的,Yii,FleaPHP等等。如果对用户的输入没有做好验证,就很容易导致一个本地文件包含漏洞。笔者曾经就在某不知名框架中发现过这样的漏洞,在不 涉及应用程序逻辑的情况下,直接获取了系统权限。
2、统一化逻辑处理
框架的一大功能就是,通过统一的入口点,可以做一些统一的安全防护、逻辑控制。在软件工程学里的说法,这个叫“面向切面编程”(AOP)。
然而我们并不是说这样的统一控制模式不好,但对于这样的统一控制,如果框架设计或实现的不好,就能直接沦陷所有跑在之上的应用。
这里有一个典型的统一处理导致安全问题的极端的例子:struts2任意代码执行漏洞。
漏洞起因是struts2希望能让用户提交的值能够直接注入到程序中的数据对象,而无需手动类型转换并给内部变量赋值等操作。为此struts2专门设计了一个叫做ognl的表达式。通过它,用户提交的参数就能被自动解析为程序上下文中所存在的变量。
想想为什么能够自动解析?原因是用户提交的参数被当作自定义语言的代码被解析执行了!只是你并没有意识到这一点而已。于是有心人研究了一下,发现ognl表达式除了参数值注入,还能通过它直接调用Java自身的API。于是,一个巨大的通杀0day就这么诞生了。
回想一下,如果struts2没有这么“智能”的自动化、统一化用户输入处理机制,也就不会出现上述的大漏洞了。
前段时间爆出的Django的csrf
token绕过漏洞也是在统一安全处理的设计上出的问题。深究一下,为什么会出现这样的绕过问题?原因就是,框架必须要对所有用户的提交在真正的应用执行
前做统一的csrf防范,于是django框架产生的token是保存在cookie中的(老版本和sessionid有关,这个也是保存在cookie
中)。对于用户提交的POST请求,表单中增加一项token,框架在获得token值后,与cookie中的正确token值比对,如果相等就通过。然
而对于ajax的请求,框架设计者却想当然的认为只要判断X-Requested-With这个Ajax特有的HTTP头即可,根本无需运算比对
token。所以,框架对于http头中包含有X-Requested-With域的请求放行。通常情况下,只有ajax的请求浏览器才会带上此自定义
域,且浏览器一般无法自定义此字段。
结果被人发现可以利用flash+307跳转可以伪造自定义http头,结果就绕过了此防范,导致统一的csrf防护毫无作用。如果应用程序完全依靠框架的统一安全实现,就会受到安全漏洞的威胁。
其实Django也很无奈,在它的架构设计中,它通过这个自定义头判断ajax思路上也没有什么问题。可惜在目前连黄瓜都不可靠的年代,就没什么是可靠的了。
3、常见代码高度封装
代码的高度封装,对外只暴露几个接口,一行说明书。这必然造成一种现象:普通程序员就像是在搭建一个模型,只要按照说明书组建积木就可以了,不需要知晓其原理,不需要知道为什么要这样做。于是这时候就安全问题就产生了。
举一个同样在用户输入参数自动化处理方面的例子:在PHP的ZendFramework中,获取用户输入是调用getParam方法,而不是常见 PHP程序中分开来的$_GET、$_POST等变量。那么,如果同时在GET、POST、COOKIE、HEADER中提交相同名字的参 数,getParam到底获取的是哪一个的值?先后顺序是什么?如果前后可以覆盖,会不会影响到我们自定义的一些统一安全措施?这是一个值得检查的安全薄 弱点。
再举一个struts2的例子:对于常见的文件上传场景,struts提供了一个FileUploadInterceptor拦截器,直接可以在应 用逻辑运行前对用户上传文件进行检查。然而在笔者的代码审计经验中,常常发现程序员只对maximumSize(文件大小)和 allowedTypes(文件mime-type)进行限制,却放过了最关键的allowedExtensions(扩展名)限制。为什么?笔者检查了 一下官方文档,发现在struts2.2之前的文档 ,都没有给出allowExtensions的说明。或许struts开发者想当然的认为allowedTypes就可以限制上传文件的类型,殊不知只要伪造HTTP包中的mime-type字段,就可以直接上传任意文件。于是开发者也就依照官方的例子 ,只限制了allowdTypes,从而导致安全问题的产生。
高度代码封装的确解决了“重复造轮子”的问题,但是它解决不了程序员的安全意识和懒惰的习惯。或许它设计的很好,或许它实现的也很好,但是只要它组装的不好,就有可能造成问题。
4、脚手架功能
Django的脚手架功能是非常好用的。它默认自带了一些app,只要通过几个简单的命令或配置,就可以在不敲一句代码的情况下搭起一个普通网站的脚手架,自带了用户注册、登陆等系统,甚至还有一个默认的管理员后台。
然而正如上文所说,普通程序员并不了解框架真正做了些什么。他很有可能通过脚手架生成网站后,却直接忘却了程序自带的内容没有去除。当这样的网站上 线后。我们发现他是Django所写,那我们就可以直接尝试在url后加入/admin/路径访问,直接猜解后台管理员密码。此外如果框架自带的默认后台 出现安全漏洞,甚至可能直接绕过进入后台。
一旦使用框架默认的组件,就得考虑到框架所带来的默认功能的安全问题。其实这问题可以扩大,tomcat自带的后台、fck编辑器自带的上传组件,都可以说属于此类问题。
0×02转
框架的应用是软件开发的必然趋势,本文的目的也不在于抵制框架的使用。但对于框架应用后所带来的新安全问题,安全从业人员需要提高重视,紧跟技术发展,更新知识。对于此,我们能够做点什么?
1、 对于常见的应用场景,如文件操作、命令行操作、数据库操作、用户权限及认证等,我们需要了解框架的实现,给出相应的安全编码范例。
框架文档中给出的例子并不一定就是最好的。安全工作者必须对程序员进行安全意识的培训,让他知道如何利用框架的API去安全的组合出常用功能。
2、 对于应用漏洞挖掘,我们需要扩充字典。
框架的封装,可能引入更多的危险API或危险特性。在代码审计的过程中,需要将这些内容加入到危险词字典中。
3、 对于应用漏洞挖掘,由于框架结构所带入的新的安全薄弱点,需要专门对框架的设计及实现做检查,是否存在问题。
例如PHP框架中代码调度执行的实现、文件上传统一检查的实现、封装的变量获取形式是否可靠等。本文中提到的安全薄弱点只是一个例子,更多的还需要大家的共同挖掘。
0×03合
实际上对于一个应用的安全审计归根到底就是个思路问题。笔者一直认为,了解程序员的思路,了解框架的思路,了解应用的思路,这些才是安全审计中最花时间的。而实际上真枪实弹看代码的漏洞挖掘却只占用很小的一部分时间。
只有将这些思路融会贯通,在脑中将审计对象进行抽象建模,了解应用需要保护什么,弱点在哪里,才能更为有效和有针对性的进行代码审计、安全防护。
最后,非常感谢剑心及空虚浪子心之前的研究成果和意见,对本文的帮助极大
相关推荐
Spring框架是Java开发领域中最重要的技术之一,它是一个开源的轻量级框架,提供了全面的编程和配置模型。Spring框架的核心特性包括依赖注入(DI)、面向切面编程(AOP)、事务管理、数据访问抽象等。本杂谈将围绕...
在Web开发中,当内容宽度超过容器的宽度时,就会出现横向滚动条。这可能是由于在设计时有意为之,以展示大量的数据或者为了适应不同分辨率的设备。在HTML中,`overflow-x`属性可以用来控制元素在水平方向上的溢出...
SSH框架是Java Web开发中的一种常见组合,由Struts2、Spring和Hibernate三个开源框架组成。这个框架结合了Struts2的MVC设计模式、Spring的依赖注入(DI)和面向切面编程(AOP)以及Hibernate的对象关系映射(ORM)...
SSH框架是Java Web开发中广泛使用的三大开源框架的组合,包括Spring、Struts2和Hibernate。这个在线服装商店项目就是基于这些技术构建的电子商务平台。接下来,我们将详细探讨SSH框架的各自职责以及如何在在线购物...
SpringMVC与Spring整合是Web应用开发的常见场景。作者讨论了SpringMVC与Hibernate的集成,以及在这个过程中可能遇到的问题和解决方案。他还深入解析了AspectJ的切入点表达式,这是Spring AOP中用于定义关注点的关键...
在技术架构选型方面,根据文档和团队成员的熟悉程度,可能选用Spring Cloud作为后端服务开发框架。Spring Cloud是目前流行的开发框架,而Spring Boot作为后台开发技术,因其上手速度快而成为主流选择。对于前端开发...
web 层框架 Spring MVC Webflux 持久层框架 Hibernate Mybatis 消息中间件框架 ActiveMQ kafka 全文搜索引擎 ElasticSearch DSL语法 Kibana 微服务架构 Spring Boot Spring Cloud 开发语言 Java JavaSE JavaEE SQL ...
它的出现,尤其是在Google Suggest和Google Map等应用中的运用,对Web开发领域产生了深远影响。Ajax的核心是利用JavaScript来实现页面局部更新,无需刷新整个页面即可与服务器进行数据交换,提升了用户的交互体验。 ...
JavaScript,简称JS,是一种广泛应用于Web开发的轻量级编程语言,主要负责网页的动态交互。作为客户端脚本语言,它常与HTML和CSS一起,构成网页开发的三剑客。文档"js代码杂谈总结.doc"显然包含了作者对JavaScript...
- **主体架构选择**:论文选择了传统的SSH(Spring+Struts+Hibernate)架构作为基础架构,这是一套成熟的Java Web应用开发框架组合,可以有效地支持Web应用的开发。 - **规则引擎集成**:论文引入了Drools规则引擎,...
- Go对WEB开发的支持,提供了标准的库和框架,便于进行WEB应用程序的开发; - Go运行时的内存管理,垃圾回收机制,以及slice和map等数据结构的使用; - Go在现代编程中处理难题的方法,比如并发编程、网络编程等。 ...
### Java框架知识学习 #### Struts 1.x **手写MVC框架** - **概念理解**:在探讨Struts框架之前,先了解MVC(Model-View-Controller)架构模式...通过这些知识点的学习,可以深入理解Java Web开发的核心技术和实践。
C#是一种面向对象的编程语言,设计用于.NET Framework,它具有类型安全、垃圾回收等特性,适合开发高性能的应用程序。 MySQL是一款开源的关系型数据库管理系统,广泛应用于Web应用、企业级系统以及大数据处理等领域...
8. **RUP(Rational Unified Process)初识**:RUP 是一种软件开发过程框架,本节介绍其基本理念和应用。 9. **测试案例设计之场景法**:讲解了如何运用场景法设计复杂的测试场景,以更全面地覆盖业务流程。 10. *...
在听微服务之前,因为学员层次不一,希望大家有了解到至少一个单体架构的web项目开发经验或大致流程,这样学起来更轻松哦! 聪明的老外总是能先于我们发现新的高效的开发模式,近几年前一个老头就提出了我们将要学习...