核心防御机制之处理用户访问、处理用户输入
核心防御机制
web应用的基本安全问题就是所有用户输入都不可信,这一点要有清晰的认识,必须假设用户所有输入都不可信,并且进行相应的过滤,才能较大可能排除哪些不坏好意的输入。Web应用采用的防御机制基本是由一下几个核心因素构成的:
1、处理用户访问应用程序的数据与功能,防止用户获得未授权的访问。
2、处理用户对应用程序的输入,防止错误输入造成的不当行为。
3、处理攻击者,确保应用程序在称为直接攻击目标是能够正常运转,并采取适当的防御与攻击措施挫败攻击者。
4、管理应用程序本身,帮助管理员监控它的行为,配置其功能。
一个典型的应用程序的绝大多数受攻击面也是由这些机制构成的。
注:受攻击面是指对未通过验证的用户的有效功能,也就是说,未通过验证的用户通过软件的默认配置能够达到什么目的。
处理用户访问
几乎任何的Web应用程序都必须满足一个中心安全要求,那就是处理用户访问其数据和功能。一般用户可以分为几种类型,如匿名用户(游客)、正常通过验证的用户和管理用户。大家平时喜欢上网应该都会有所了解。一般不同的用户也是只允许不同的数据,游客可能就无法实现一些功能,验证用户也只能访问服务器里属于自己的信息,管理员用户就不用说了。
大多数Web Application实用3层相互关联的安全机制来对用户访问进行处理:
1、身份验证
2、会话管理
3、访问控制
这三者都是应用程序受攻击面的一个关键部分,对于应用程序的的安全很重要,这三者相互依赖,任何一个部分存在缺陷被突破,攻击者就可以达到访问应用程序功能和数据的目的。
身份验证
这个机制试应用程序里处理用户访问的最基本的机制,说简单点就是,确认访问者的真实身份。不使用这个机制将会带来的问题就是,不利于用户管理和数据安全,所有用户都被作为匿名用户对待,将会出现一些问题。
目前,绝大多数的Web application都会实用传统的身份验证模型,也就是要求用户提交用户名和密码,然后应用程序去核实情况,来确认合法与否。当然一些对安全性要求较高的应用程序还会实用其他手段来验证,例如其他证书和多阶段登录过程强化,甚至实用客户端证书、智能卡等。这个银行的application就很明显了,大家使用网上银行的时候可能都会被要求安装数字证书等。除了进行身份验证,身份验证机制一般还会提供一些支持型功能,比如大家熟悉的账号注册,密码找回和密码修改。
但是身份验证机制的设计和执行方面,还是会存在缺陷。攻击者可能可以确定其他用户用户名、并且通过一定手段推测它们密码,又或者利用验证系统在设计时的缺陷,绕过登陆验证。攻击者甚至会攻击应用程序采用的与身份验证有关的功能,借此来非法访问数据。
会话管理
身份验证结束后,用户也就登录成功了,那么就可以使用一些功能和访问一些页面,那么浏览器就会发出一系列的HTTP请求。同时其他用户可能也在发出无数请求。为了可以有效的访问控制,就必须要识别来自每一位用户的请求。所以应用程序就为每一个用户建立一个会话,并且向用户发布一个标识会话的令牌。令牌是一个唯一的字符串,唯一标识一个用户。通过令牌,浏览器的HTTP请求就可以被应用程序识别,并把请求与用户关联起来。虽然很多的应用使用隐藏表单字段或URL查询字符串传送session token,当HTTP cookie才是实现这一目的的常规方法。这就是为什么攻击者会使用XSS攻击偷取cookie然后伪造用户访问或进行CSRF攻击。如果用户一段时间没有发出请求,会话就会自动终结。
所以会话管理的关键就在于Token的安全,大多数攻击者都会想要获取用户令牌。如果可以偷取到令牌,攻击者就可以伪装用户使用应用程序。令牌生成过程中存在的缺陷是主要的漏洞来源,攻击者能够推测发给用户的令牌,然后去截获令牌。也有少数应用不使用令牌,而是使用其他方法来确认用户身份。有时应用程序会将状态信息存储在客户端而非服务器,并且对这些信息进行加密。
访问控制
访问控制是前两者正常工作后一个重要的机制,它需要进行正确决策,决定允许还是拒绝认证用户的请求。这是一个很关键的过程,需要是实现进行设计的逻辑,考虑应用领域和不同类型功能,需要根据请求访问者的身份,来判断其是否有相关权限。甚至对一些特殊操作及进行较为严格的访问控制和检查。但是访问控制比较复杂,所以在一些权限的配置上可能存在疏忽,从而导致漏洞,或者开发者在开发时对一些功能存在错误判断,使攻击者可以未经授权访问应用程序的数据和功能。但是寻找访问控制上的漏洞也是一件费力的工作,必须要一个一个重复进行检查。当一旦成功,也会造成一定的损失。
处理用户输入
所有用户输入都不可信。所有必须要采取一定的措施来过滤和避免有人输入恶意内容。因此必须要安全处理用户输入,这是应用程序安全的一个关键。通常输入确认是防御这些攻击的必要手段,但是任何一种保护机制都不是绝对安全的。
输入的多样性
在许多情况下,应用程序可能会对一些特殊输入实行非常严格的确认检查。所以你会看到在注册一个账号的时,网站会对用户名和密码的字符有要求,如长度,所能包含的字符。
在其他情况下,可能要接受更加广泛的输入。比如说填写地址就会涉及到很多的字符。但是依旧要对字段进行有效限制。比如不能超过最大长度,不能包含一些HTML等语言的标记。
还有一些场景,应用必须完全接受用户提交的完全任意的输入,例如想****博客一样,我在这里写博客,博客里可能会含有一些有害的字段(演示用),但是****有不能拒绝我这样写作。所以就要想办法来解决这个问题,并且要以安全的方式来向用户显示。
输入处理方式
通常可以采用各种方法来处理用户输入,不同方法一般使用与不同的情形与不同类型的输入,有时最好结合采用几种方法。
1、拒绝已知的不良输入
这个一般使用黑名单来进行字符串或模式的匹配,并且阻止任何与黑名单匹配的数据,并接受其他数据。不过这个有点不太好,效率不高,目前攻击的字符语句越来越多,各式各样。加上不同的编码方式赋予了攻击语句不同的形似,而且很可能会忽略某些攻击语句和模式,很明显黑名单无法满足满足需求。
2、接受已知的正常输入
这个和上面的刚好相反,这个就是个白名单,在某种意义上它似乎对于处理恶意输入很有效,因为只有白名单可以接受,其他统统不要,而制定白名单的是否肯定很谨慎,所以基本上恶意输入可以被过滤掉,但是它同时会给用户的输入带来不太好的体验,可能无法满足用户的输入需求,比较死板。所以虽然它极其有效,但是基于白名单的方法并非是解决处理用户输入问题的万能办法。
3、净化
这种方法允许有时需要接受无法保证安全的数据,application不拒绝这种输入,而是,以各种方法来净化,防止它造成任何不利的影响。数据中可能存在的恶意字符会被删除,只留下安全字符。或者在进一步处理前对它进行编码或转义。基于数据净化的方法一般非常有效。比如可以在危险字符植入应用页面前对其进行HTML编码,这是防XSS攻击的常用方法,目前有很多网页都是把危险脚本进行HTML编码,使其无法达到目的。但是如果是一个输入包含多种而已数据,这个净化就不太OK了,这时最好就要使用边界确认来解决了。
4、安全数据处理
以不安全的方式处理用户提交的数据,是许多Web应用程序漏洞形成的根本原因。通常,不需要确认输入本身,只需确保处理过程绝对安全,就可以避免这些漏洞。有时候可以使用安全的编程方法避免常见问题。例如在数据库访问过程中正确使用参数化查询,就可以避免SQL注入攻击。
5、语法检查
,就可以避免这些漏洞。有时候可以使用安全的编程方法避免常见问题。例如在数据库访问过程中正确使用参数化查询,就可以避免SQL注入攻击。
5、语法检查
当攻击者提交的输入于普通的非恶意用户提交的输入完全相同,再多的语法确认也无法区别用户和攻击者的数据。为了防止未授权的访问,应用程序必须确认所提交的账号属于之前提交该账户的用户。