Search code examples
angularjsacl

Bullet-Proof ACL using AngularJS


I am new to AngularJS and trying to grasp the concept of implementing an access control layer so that some pages/menus will be hidden from certain users.

I usually implement ACL and all routes on the back-end (PHP/MySQL) but this project require me to do everything on the client side only.

We have a remote server that is in charge of authentication and upon successful login, will return an is_admin flag so that I know whether to display the additional info.

Although not likely, since Angular is also the rendering engine and is in charge of all the logic, I am afraid that users will be able to play with browser developer tools and/or other 3rd party tools and gain access to those areas (since all scripts & logic will be visible to them in the browser).

So if I do something like:

     if (user.is_admin === true) 
        {
            //display the additional admin data...
        }

A user can potentially set user.is_admin = true in the browser tools and gain access.

With server side rendering such as PHP, the user will never be able to even know about these hidden areas. i.e

    <?php 
       if ($user->is_admin === true) {...}//user will never ever see that or be able to modify $user properties
    ?>

Of course that the server will keep on authenticating every request so this exploit will only allow limited access, but still seems like a non secure way of hiding sections from certain users.

Am I missing something in Angular or is there a better way of doing it so that it's bullet-proof for client side hacks?


Solution

  • The Angular way of hiding sections is with the ng-if/ng-show/ng-hide directives, as in:

    <div ng-if="is_admin">...</div>
    

    You can't hide those divs from people who look at the source, or the resources you make available in your app. So don't provide admin data to those views.

    My approach was to make an "admin" app in addition to the "standard" app and link between them. This way, the only things exposed are links to the admin site, which are blocked to non-admin users:

    <div ng-if="is_admin"><a href="/admin/#/link">Link</a></div>
    

    All requests to my /admin/* pages return a 401 status code if they are not an admin. The REST resources also return 401 status codes as appropriate.

    (Edit: changed above ng-hide to ng-if to suppress those divs in the resulting DOM.)