web application 访问控制

http://secappdev.org/handouts/2012/Jim%20Manico%20%26%20%20Eoin%20Keary/Final%20-%20Access%20Control%20Module%20v4.1.pdf

什么是access control/authorization?

authorization is the process where a system determines if a specific user has access to a particular resource.

在上面的定义中有几个关键词: process, specific user, particular resource

authorization的目的是ensure that a user only access system functionality to which he is entitled.也就是说让用户具有已经赋予他的权利来访问他可以访问的资源

 

凡是网站有用户就有访问控制的需求,传统上基于RBAC(Role based access control)可以实现粗放的访问控制,但是RBAC也有非常明显的问题:就是控制粒度太大,无法动态对某个资源来实现控制,要么可以访问,要么不能访问,而现实中很多情况下是:可以读访问部分资源,读写自己创建的资源,这种情况下RBAC就无能为力了。总的来说,RBAC无法解决水平访问控制的问题(horizontal access control)

 

access control的分类

访问控制总体来说可以分为3类: vertical, horizontal, context-dependent

vertical access control:允许不同类型的用户访问应用的不同功能。最简单的情况比如将普通用户和管理员用户做一个垂直划分,他们能够访问应用的不同部分,比如只有admin用户能够访问管理后台;在更复杂的情况下,vertical access control可能包含着定义良好的user roles并且给这些roles授权specific functions.

horizontal access control则允许用户访问一个相同类型大的资源池中的子集(allow users to access a certain subset of a wider range of resources of the same type)比如,一个web mail application允许你查阅你自己的email,但是不允许你查看别人的email(尽管这些email对于系统来说就是一种相同类型的资源),一个线上银行允许你将你的帐号的钱转出去,但是不允许转别人的钱,一个工作流应用允许你更新分配给你的tasks,但是却只允许你read tasks assigned to other people(NON write access).

context-dependent access controls确保用户的访问权限和当前application state有关。比如,如果一个用户在一个长流程中的不同阶段时,context-dependent access control可能拒绝你访问未按照流程走完的访问请求。

大多数情况下,vertical和horizontal access control是交织在一起的。比如,一个enterprise resource planning application可能允许每个应付账店员对于他负责的organizational unit付账,但是不允许对其他的unit付账。而部门经理可能被允许pay invoices for any unit.类似的,店员可能被允许支付小额账单,但是大额账单却只能由manager来启动支付。而财务总监可能能够查看公司任何一个organizational unit的应付账清单,但是却不允许启动付账流程。

如果只要任何用户能够访问未授予他权限的functionality or resources我们都认为access control is broken.有三种主要的attacks against access controls,对应着三种access control category:

对访问控制的恶意攻击

1. Vertical access control attacks

    一个低权限的用户能够访问未授权给他的高权限功能functions(a standard user accessing administration functionality)。比如,如果一个普通用户可以执行管理功能,或者一个店员能够启动任何金额的应付账,则access controls are broken

2. Horizontal access control attacks

    相同角色的用户去访问其他用户的私有数据(same role, but accessing another user's private data).当一个用户可以查看或者修改他未被授权访问的resource时就认为access controls are broken.比如,如果你使用web mail可以查看其他用户的email,或者应付账部门员工可以处理不是他负责的部门的账单则就认为broken

3. Business logic access control attacks

   abuse of workflow

   如果一个用户可以利用应用的状态机缺陷来获取到一个关键resource.比如,一个用户可能在checkout shopping cart时绕过payment step而却实现了购物的成功。

通常一旦应用的horizontal access control缺陷可能能够马上导致vertical attack.比如,如果一个用户可以找到一个办法来设置别的用户的密码,那么这个用户可能就可以修改admin账户密码从而得到对应用的绝对控制。

 

访问控制经常存在的issues

1. 很多application仅实现了一个"all or nothing" approach:一旦authenticated那么所有用户都有相同的权限

2. authorization logic通常依赖于默认环境是安全的并且会假设:用户不会找到unlinked functionality或者说是hidden path/functionality, 用户不会找到并且篡改那些隐藏的客户端参数(比如:hidden form filed, cookies等)

比如:在访问一个页面a.com/profile时,如果他登录为administrator用户,则在视图层中就返回一个a.com/adminbackend的页面链接以方便点击,而如果不登录为admin帐号则view中就不包含这个后台链接,而对这个后台链接遗憾的是应用并未做任何保护,那么这种所谓的保护(仅通过根据不同用户来决定是否显示受限访问链接来"保护")是假设在别人无法知道这个a.com/adminbackend url上的。一旦别人知道了这个链接直接访问则门户洞开。

 

3. 在应用中一旦有了多个permission level/roles这总会增加permission set间权限冲突可能从而使得权限系统工作紊乱

典型的权限控制不好的实现实践

1. 在application code中hard-coded role check

void   editProfile(User u, EditUser eu) {   if (u.isManager()) { editUser(eu)     } } 

带来的问题: what needs to occur in order to change the access control policy of this feature?

 a. 使得证明我们已经实现了应用的授权策略非常困难

 b. 任何时候访问控制策略policy需要变更,那么就必须修改代码

 c. 脆弱而易于犯错误

 d. 无法实现自动化,需要在每一个application feature上来做hand-coded

 

2. 缺乏集中的访问控制逻辑

看看下面的分散参数控制情况: 

http://example.com/buy?action=chooseDataPackage
http://example.com/buy?action=customizePackage
http://example.com/buy?action=makePayment
http://example.com/buy?action=downloadData
攻击者可以通过concurrency就可能获取不应有的权限

3. 不可信数据却驱动着访问控制决策

 a. 永远不要信任从客户端来的数据做访问控制决策

 b. 永远不要在javascript中做访问控制决策

 c. 永远不要只基于以下信息来做访问控制决策:

    c.1: hidden fields

    c.2: cookie value

    c.3: form parameters

    c.4: url parameters

 d. 永远不要依赖于客户端发送过来参数值的顺序来做决策

 

4. 访问控制遵循了"open by default”的原则,这将开放不必要的权限

   很多administrative interfaces仅仅需要一个密码就授权了。共享帐号而又缺乏auditing和logging会导致区分好人和坏人非常困难。admin interface往往不如user-level interface那么安全因为总是假设administrators是值得信任的用户

 

 

5. 缺乏解决水平访问控制的标准方法

6. access contro逻辑必须手工地加到每一个endpoin中

攻击访问控制系统

1. elevation of privileges

2. 披露敏感信息: 比如admin-level的帐号往往能够访问一个用户的私密信息

3. 数据篡改: 特权级别往往对于那些可以查看数据的用户和可以修改用户的数据不加以区分

testing for broken access control

试图作为一个匿名用户或者一个普通用户来访问admin components/functions:修改html hidden form fields, 测试web accessible directory structure for names,比如admin,administrator,manager等等:即直接访问那些受限的资源

试图摸清administrator是如何被authenticated的。我们需要确保充足的鉴权渠道被使用,甚至可以加上普通密码加上注册手机得到的临时密码来鉴权

对于每一个user role,需要确保适当的pages或者components可以被那个role所访问

Access control best practices:

1. 通过role based access control来对用户assign permissions以实现vertical access control requirements;

2. 通过data-contextual access control在特定data items上下文环境中授权给特定用户以实现horizontal access control requirements

3. 避免直接对单个用户来做assign permissions动作

4. 对应用的所有pages都执行一致的authorization checking routings;

5. 如果可能,在最后应用apply DENY, case-by-case来 issue allow privilege

6. 实现一个集中的access control mechanism

7. code to the activity(permission), not the role

 8. 集中access control logic

9. 将access control作为一个filter或者说middleware

10. Deny by default, fail securely

11. 将相同的核心授权逻辑应用到presentation(view视图)层和server-side access-control decisions中

12. server-side受信数据应该作为驱动access-control的数据源头

13. 可以在实时运行时修改一个用户的role

14. build grouping capability for users and permissions

Code to the activity/permission

// 不再像下面的
if ((user.isManager() ||     user.isAdministrator() ||     user.isEditor() ||    user.isUser() &&     user.id() != 1132)) {     //execute action}
// 而应该像这样:
if (AC.hasAccess(ARTICLE_EDIT)) {   //execute activity}

code it once, never needs to change again

implies policy is persisted/centralized in some way

requires more design/work up front to get right

定义一个centralized ACL Controller:定义一个集中的ACL Controller

ACLService.isAuthorized(ACTION_CONSTANT) 
ACLService.assertAuthorized(ACTION_CONSTANT)

所有的access control decision都通过这些简单的api来实现

集中的授权逻辑驱动policy behavir and persistence

可能包含data-driven access control policy information

如何使用一个centralized access controller

1. 在视图presntation layer:

if (isAuthorized(VIEW_LOG_PANEL)){   
<h2>Here are the logs</h2>  
<%=getLogs();%/>
} 

2. 在控制层controller中:

try (assertAuthorized(DELETE_USER)){  
 deleteUser();
}

永远在server端验证policy:

1. 将user id verification放在session中;

2. 从受信任的server端数据源头来加载entitlements

3. 对所有的requests都强制authorization check: 包括js文件发起的request,mage, ajax, flash request都要强制authorization check, 最好通过一个通用的middleware来实现这个强制鉴权功能

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值