《白帽子讲Web安全》9-10章
9、认证与会话管理
注入攻击的本质,是把用户输入的数据当做代码执行。这里有两个关键条件,第一个是用户能够控制输入;第二个是原本程序要执行的代码,拼接了用户输入的数据。
9.1、Who am I?
认证:Authentication
授权:Authorization
- 认证:用于识别用户身份,相当于用钥匙开门进入屋子。钥匙在认证过程中被称为“凭证”,开门过程对应互联网中的登录。
- 授权:决定用户在进入系统后能做什么。比如,主人可以在屋子里做任何事,而客人只能在沙发上看电视。授权依赖于认证,只有识别出用户身份后才能进行授权。
- 认证的安全性:如果钥匙丢失或被复制,系统安全会受到威胁。认证手段多样化,包括指纹、虹膜等生物特征。单因素认证使用一个凭证,多因素认证使用多个凭证,后者更安全但可能影响用户体验。
认证是识别用户身份的过程,而授权是决定用户权限的过程。
9.2、密码的那些事儿
密码认证的优缺点
- 优点:使用成本低,认证过程简单。
- 缺点:安全性较弱,容易被猜解。实现安全的密码认证方案并不容易。
黑客常用的攻击手段
- 暴力破解:通过猜解弱口令(如 123456)和用户名,找到使用弱口令的账户。由于用户名通常是公开的,这种攻击成本低且效果好。
密码保存的注意事项
- 加密存储:密码必须使用不可逆的加密算法或单向散列函数(如 MD5、SHA-1)加密后存储在数据库中,以保证密码的私密性。
- 哈希保存:用户注册时将密码哈希后保存,登录时验证用户提交的哈希值是否与数据库中的一致。
彩虹表攻击及防范
- 彩虹表:通过收集大量密码明文及其对应的 MD5 值,黑客可以通过查询 MD5 值找到对应的明文。
- 防范措施:使用“Salt”增加明文复杂度,使彩虹表攻击失效。Salt 是一个随机字符串,保存在服务器端配置文件中。
MD5(Username + Password + Salt)
9.3、多因素认证
除了支付密码外,手机动态口令、数字证书、宝令、支付盾、第三方证书等都可用于用户认证。这些不同的认证手段可以互相结合,使得认证的过程更加安全。密码不再是唯一的认证手段,在用户密码丢失的情况下,也有可能有效地保护用户账户的安全。
9.4、Session与认证
SessionID一旦在生命周期内被窃取,就等同于账户失窃。同时由于SessionIlD是用户登录之后才持有的认证凭证,因此黑客不需要再攻击登录过程(比如密码),在设计安全方案时需要意识到这一点。
-
SessionID与认证:
- 认证手段(如密码和证书)用于登录过程。
- 登录成功后,使用SessionID作为对用户透明的凭证。
- 服务器端创建会话(Session)保存用户状态和信息,浏览器通过SessionID告知服务器使用哪个Session。
-
SessionID的存储:
- 通常将SessionID加密后保存在Cookie中,利用浏览器的同源策略保护。
- 由于某些手机浏览器不支持Cookie,SessionID也可能保存在URL中,但这种方式安全性较低。
- Session劫持:
- 通过窃取SessionID登录目标账户,称为Session劫持。如果SessionID保存在Cookie中,则称为Cookie劫持。
- 通过Referer泄露URL中的SessionID是常见问题。(手机浏览器在解析图片时,实际上是发起了一次GET请求,这个请求会带上Referer,在服务器端可以看得到此值)
-
生成SessionID的安全性:
- 需要保证足够的随机性,采用强伪随机数生成算法。
- 使用成熟的开发框架提供的Cookie管理和Session管理功能。
9.5、Session Fixation攻击
什么是Session Fixation呢?举一个形象的例子,假设A有一辆汽车,A把汽车卖给了B,但是A并没有把所有的车钥匙交给B,还自己藏下了一把。这时候如果B没有给车换锁的话,A仍然是可以用藏下的钥匙使用汽车的。
这个没有换“锁”而导致的安全问题,就是Session Fixation问题。
-
攻击过程:
- 攻击者X获取一个未经认证的SessionID。
- 将此SessionID交给用户Y进行认证。
- 用户Y认证成功后,服务器未更新SessionID,X可用此SessionID登录Y的账户。
-
SessionID的传递:
- Cookie中:较难让用户Y使用指定的SessionID。
- URL中:攻击者X可诱使用户Y打开包含SessionID的URL。
-
防御方法:
- 登录完成后重写SessionID。
- 使用sid时重置其值;使用Cookie时增加或改变用于认证的Cookie值。
9.6、Session保持攻击
-
Session生命周期:
- 用户长时间未活动或点击退出后,服务器销毁Session。
- Session未失效可能导致Session劫持攻击,攻击者通过持有有效SessionID登录用户账户。
-
攻击者保持Session的方法:
- 间隔性刷新页面,告诉服务器用户仍在活动。
- 通过自定义Cookie头的HTTP包保持Session状态(SessionIE工具)。
-
Cookie和Session的失效:
- 一般应用设置Session失效时间,过期后销毁。
- 某些系统为用户体验考虑,只要用户“活着”,Session不失效,攻击者可通过不停访问保持Session。
-
服务器端不维护Session的做法:
- 将Session加密保存在Cookie中,浏览器访问时自动带上,服务器解密获取Session。
- Cookie的Expire标签控制Session失效时间,攻击者可篡改Expire时间使Session永久有效。
-
对抗Session保持攻击的方法:
- 强制销毁Session:设定一个阈值(如3天)后强制Session过期。
- 客户端变化时重新登录:如IP、UserAgent变化时强制销毁Session并要求重新登录。
- 限制每个用户同时拥有的有效Session数量:用户再次登录时,旧Session失效。
9.7、单点登录(SSO)
单点登录的英文全称是Single Sign On,简称SSO。用户只需要登录一次,就可以访问所有的系统。从用户体验的角度看,SSO无疑让用户的使用更加的方便;从安全的角度看,SSO把风险集中在单点上,这样做是有利有弊的。
优点
- 用户体验:用户只需一次登录,使用更加方便。
- 风险集中化:只需保护一个登录点,安全标准更容易统一。
- 安全性:可以在单点处设计更复杂的安全方案,如双因素认证。
- 成本效益:中小网站可以将登录管理委托给可信的第三方,减少维护成本。
缺点
- 风险集中:一旦单点被攻破,所有系统都可能受到影响。防御办法:在敏感系统中需要额外的认证机制,如再次输入密码或短信验证。
目前互联网上最为开放和流行的单点登录系统是OpenID。OpenID是一个开放的单点登录框架,它希望使用URI作为用户在互联网上的身份标识,每个用户(End User)将拥有一个唯一的URI。在用户登录网站(Relying Party)时,用户只需要提交他的OpenID(就是用户唯一的URI)以及OpenID 的提供者(OpenID Provider),网站就会将用户重定向到OpenIlD 的提供者进行认证,认证完成后再重定向回网站。OpenID 的提供者服务水平也有高有低,作为OpenID的提供者,一旦网站中断服务或者关闭,都将给用户带来很大的不便。
9.8、小结
10、访问控制
10.1、What Can I Do?
权限控制,或者说访问控制,广泛应用于各个系统中。抽象地说,都是某个主体(subject)对某个客体(object)需要实施某种操作(operation),而系统对这种操作的限制就是权限控制。
-
在网络中,为了保护网络资源的安全,一般是通过路由设备或者防火墙建立基于IP的访问控制。
- 访问控制的“主体”是网络请求的发起方(比如一台 PC);
- “客体”是网络请求的接收方(比如一台服务器);
- 主体对客体的“操作”是对客体的某个端口发起网络请求;
这个操作能否执行成功,是受到防火墙ACL策略限制的。
-
在操作系统中,对文件的访问也有访问控制。
- “主体”是系统的用户,
- “客体”是被访问的文件,
- 能否访问成功,将由操作系统给文件设置的ACL(访问控制列表)决定。
在一个安全系统中,确定主体的身份是“认证”解决的问题;而客体是一种资源,是主体发起的请求的对象。在主体对客体进行操作的过程中,系统控制主体不能“无限制”地对客体进行操作,这个过程就是“访问控制”。
在Web应用中,根据访问客体的不同,常见的访问控制可以分为“基于URL的访问控制”、“基于方法( method)的访问控制”和“基于数据的访问控制”。
-
基于 URL 的访问控制
- 定义:限制用户对特定 URL 的访问。
- 实现方式:通过服务器配置或应用程序代码,根据用户角色或权限控制对特定 URL 的访问。
- 应用场景:适用于需要保护特定网页或 API 端点的应用。例如,只有管理员可以访问管理后台页面。
-
基于方法的访问控制
- 定义:限制用户对特定方法或功能的访问。
- 实现方式:在代码中使用注解、拦截器或配置文件,根据用户角色或权限控制对特定方法的调用。
- 应用场景:适用于需要对具体操作进行严格控制的应用。例如,只有财务管理员可以调用资金转账方法。
-
基于数据的访问控制
- 定义:限制用户对特定数据或资源的访问。
- 实现方式:通过后端代码或数据库配置,根据用户角色或权限控制对数据的访问。
- 应用场景:适用于需要保护敏感数据的应用。例如,只有特定用户可以访问某些文件夹或文档。
10.2、垂直权限管理
访问控制实际上是建立用户与权限之间的对应关系,现在应用广泛的一种方法,就是“基于角色的访问控制(Role-Based Access Control)”,简称RBAC。
RBAC事先会在系统中定义出不同的角色,不同的角色拥有不同的权限,一个角色实际上就是一个权限的集合。而系统的所有用户都会被分配到不同的角色中,一个用户可能拥有多个角色,角色之间有高低之分(权限高低)。在系统验证权限时,只需要验证用户所属的角色,然后就可以根据该角色所拥有的权限进行授权了。
这种基于角色的权限管理(RBAC模型),我们可以称之为“垂直权限管理”。
Spring Security提供了一系列的“Filter Chain”,每个安全检查的功能都会插入在这个链条中。在与Web系统集成时,开发者只需要将所有用户请求的URL都引入到Filter Chain即可。
在 Spring Security 中,过滤器链(Filter Chain)是一个核心概念,用于处理 HTTP 请求的安全性。它由一系列过滤器组成,每个过滤器都有特定的职责。以下是过滤器链的主要特点和工作原理:
-
主要特点
- 标准 Servlet 过滤器:Spring Security 的过滤器链基于标准的 Servlet 过滤器实现。
- 责任分离:每个过滤器负责特定的安全任务,如身份验证、授权、会话管理等。
- 顺序执行:过滤器按照配置的顺序依次执行,顺序非常重要,因为某些过滤器依赖于前面的过滤器。
-
工作原理
- 请求拦截:当一个 HTTP 请求到达应用程序时,
FilterChainProxy
会拦截该请求。 - 匹配过滤器链:
FilterChainProxy
根据请求的路径和配置的SecurityFilterChain
决定将请求转发给哪个过滤器链实例。 - 执行过滤器:匹配的过滤器链中的每个过滤器依次处理请求,执行相应的安全检查和处理。
- 请求拦截:当一个 HTTP 请求到达应用程序时,
Spring Security提供两种权限管理方式,一种是“基于URL的访问控制”,一种是“基于method的访问控制”。这两种访问控制都是RBAC模型的实现,换言之,在Spring Security 中都是验证该用户所属的角色,以决定是否授权。
虽然Spring Security 的权限管理功能非常强大,但它缺乏一个管理界面可供用户灵活配置,因此每次调整权限时,都需要重新修改配置文件或代码。而其配置文件较为复杂,学习成本较高,维护成本也很高。
除了Spring Security外,在 PHP的流行框架“Zend Framework”中,使用的Zend ACL实现了一些基础的权限管理。不同于Spring Security使用配置文件管理权限,Zend ACL提供的是API级的权限框架。
10.3、水平权限管理
在基于角色的访问控制 (RBAC) 模型下,用户A和用户B虽然同属于角色RoleX,但各自拥有的私有数据应仅由自己访问。然而,RBAC 只验证用户是否属于某角色,而不判断用户是否能访问其他用户的数据,导致越权访问问题,即“水平权限管理问题”。
水平权限管理问题出现在同一角色内,系统缺乏对角色内用户和数据子集的细分,导致用户与数据之间缺乏对应关系。这种问题也被称为“基于数据的访问控制”。
-
数据级权限管理问题
- 发现难度:大型复杂系统难以通过自动化测试发现所有水平权限问题。
- 业务紧密结合:数据访问控制需求与具体业务紧密相关,不同业务需求不同。
- 系统改动:上线后处理数据级访问控制问题可能涉及跨表、跨库查询,影响系统性能。
-
解决方案
- 用户组:使用用户组概念,确保数据只属于该组内成员。
- 规则引擎:通过配置文件定义访问控制规则,使用规则引擎控制数据访问。
属性基访问控制(Attribute-Based Access Control, ABAC)是一种灵活且强大的访问控制方法,通过评估与用户、资源、操作和环境相关的属性来决定是否授权访问。
Github的私有化仓库通过ABAC实现水平权限管理。
10.4、OAuth简介
OAuth是一个在不提供用户名和密码的情况下,授权第三方应用访问Web资源的安全协议。
常见的应用OAuth的场景,一般是某个网站想要获取一个用户在第三方网站中的某些资源或服务。
我们再来看一个实际场景。假设Jane在 faji.com 上有两张照片,她想将这两张照片分享到beppa.com,通过OAuth,这个过程是如何实现的呢?
Jane在 beppa.com 上,选择要从faji.com上分享照片。
在beppa.com后台,则会创建一个临时凭证(Temporary Credentials),稍后Jane将持此临时凭证前往faji.com。
然后页面跳转到faji.com 的OAuth页面,并要求Jane登录。注意,这里是在 faji.com 上登录!
登录成功后,faji.com会询问Jane是否授权beppa.com访问Jane在faji.com里的私有照片。
如果Jane授权成功(点击“Approve”按钮),faji.com会将Jane带来的临时凭证(Temporary Credentials)标记为“Jane已经授权”,同时跳转回beppa.com,并带上临时凭证(Temporary Credentials)。凭此,beppa.com知道它可以去获取Jane的私有照片了。
对于beppa.com来说,它首先通过Request Token去 faji.com换取Access Token,然后就可以用Access Token访问资源了。Request Token只能用于获取用户的授权,Access Token才能用于访问用户的资源。
最终,Jane成功地将她的照片从 faji.com分享到beppa.com 上。
使用微信、QQ等账户登录第三方应用或网站也属于OAuth 使用场景之一。
10.5、小结
访问控制与业务需求息息相关,并非一个单纯的安全问题。因此在解决此类问题或者设计权限控制方案时,要重视业务的意见。
最后,无论选择哪种访问控制方式,在设计方案时都应该满足“最小权限原则”,这是权限管理的黄金法则。