zoukankan      html  css  js  c++  java
  • 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来实现这个强制鉴权功能

     

  • 相关阅读:
    利用JavaScript制作网页中“选项卡”效果。 (二)
    Threading and UI
    我不太喜欢的一篇文章: [真爱无言]
    坚持,习惯,自然
    6行代码实现无组建上传(转)
    【转帖】20个你未必知道的CSS技巧
    CSS Filter 代替 图片 实现 渐变背景效果。
    Microsoft Excelに...
    ATM机的故事
    利用JavaScript制作网页中“选项卡”效果。 (三)——终极应用 JavaScript tabifier
  • 原文地址:https://www.cnblogs.com/kidsitcn/p/6367384.html
Copyright © 2011-2022 走看看