Categories: BrowserID

BrowserID: System security

With the launch of we have been busy reviewing the code and design of BrowserID.

However, we also wanted to:

  • Enforce privilege separation at the system level
  • Render the potential security issues in the web app code, and other services running less relevant

This is implemented via:

  • Role based access control (RBAC)
  • Enforced by a Mandatory access control framework (MAC)


  • With DAC, the users are responsible for setting access permissions,
    such as read, write, execute (those are set by the user owning the file).
  • With MAC, the system sets and controls the permissions, and users cannot modify permissions, even of files they own.

RBAC is an access control model, which is enforced by MAC. Note that for compatibility reasons, the
Linux DAC model is still in use. However, MAC has always precedence over DAC.


  • File system objects, and some other system objects are grouped into different types.


  • With RBAC processes (subjects) are grouped into different roles.
  • The roles have a detailed list of permissions for each type.
  • The list of permissions is called an access matrix (also called access vector).
  • The sum of the access matrices is called the RBAC security policy.

Like in a theater, where the same person can be role playing different
characters, the same processes can be started under different roles (and
even transition to other roles if those are set to be compatible).
For the BrowserID project, we have selected RSBAC as the MAC framework, which
implements a module called RC (Role Compatibility) as it’s RBAC model.

  • RSBAC allows to retain both flexibility and very detailed access control (no compromise).
  • It is a patch to the Linux kernel, which implements hooks and an access decision framework.
  • It has several security models implemented (called modules)
    • Each model can return GRANTED, NOT_GRANTED or DO_NOT_CARE (=GRANTED) for each access decision.

RSBAC modules we are using in particular:

  • RC The RBAC module
  • AUTH The authentication module
    • Lists which user ids a process is allowed to switch to.
    • You cannot login as a user, or switch to a user id, if you did not allow it through AUTH
  • CAP The capabilities module, controls Linux’s capabilities.
    • For example we disable root capabilities (root is a regular user)

Security Policy
Common approach:

  • One policy file per package.
    • Complex and require a lot of maintenance. May require repackaging each package.
    • More difficult to customize and extend the policy in some cases.
  • Policy enabled only for specific system daemons (RHEL SELinux’s does this by default: it’s called the targeted policy).
    • Easier management and setup, but if unprotected daemons/processes are compromised, this does not  help much.
    • Lower security level.

Our approach:

  • Global base policy common to all systems
    • Runs on default installs for RHEL 6 systems
    • Role per service” instead of “Role per package”
  • Extended by a custom policy file, per system type basis
    • BrowserID has such a custom policy file
    • Separate NodeJS’s daemons, keys, secure cookie storage, etc.
    • Different custom policy for the database, web servers, and so on.
  • Faster!
    • Faster deployment (no repackaging, no separate per package tests).
    • Security policy development team does not need to wait on the package team or vice-versa (in our case, RedHat, which release updates and upgrades independently)
    • The security engineer/admin only has to verify the policy works as expected on system update (generally the policy only needs update on major version upgrades like RHEL 5 to RHEL 6)

We plan to have a specific NodeJS RSBAC module, enabling us to switch role from within NodeJS depending on the operation performed, to obtain a more detailed separation.

  • Critical code sections could run with an elevated role.
  • Other parts of the process cannot elevate to this role.
    • Note that technically this is a hybrid form of MAC+DAC as the process itself decides when to switch roles, but the policy limits which role, by which process, and so on.
  • The elevated role, still has a very detaille policy which does not give access to more than what it needs.

When a regular code section has a bug and the exploitation of the bug gives system access or the ability to run system commands/access the filesystem/access the database, the attacker will be contained in their role and RSBAC will deny access to the types that the elevated role would have access to (for example, cookies and keys).

Therefore, even if the root or an administrative user was compromised,
the attacker would again, be limited by:

  • The role’s access matrix
  • The capabilities allowed for the process that has been compromised
  • Switch to the user IDs AUTH permits for this process.

In short, the detailed access control severely reduces the attack vectors.