My Opera is closing 1st of March

Covert Tomato

Spending CPU cycles associating random words

Security Included: Using the ACL Plugin

, , , ,

The UI plugin adds by default a password protection to the application. This feature stands in the sidebar section "Privacy options for [Application Name]". In this post, I explain the mechanism allowing for such security features, which is implemented by the acl plugin of Yusef.

Overview

Basically, the ACL plugin does nothing more than associating a clearance level with each URL of the application. The clearance level is technically named "access type", while the URL is referred to as a "Resource". Furthermore, the association between an URL and an access type is called an "Access Node".

The acl plugin offers the following access types:
  • accessTypes.public: Unlimited access to the resource.
  • accessTypes.limited: The resource is only available if you have the password.
  • accessTypes.private: The resource is restricted to the owner of the application.


Apart from associating URL to access types, an access node has also a strictness parameter. If an access node is strict, the access type of a resource cannot be changed. Ever.

Getting Started: a Page for the Almighty Owner

Defining a Section
Now that the main terms are defined, we will build a owner-only option page as a practical example. This page will actually be a section of the application. The following code builds such a page and restricts the access to the sole owner:
Yusef.addSectionListener
(
  'options',
  function(connection) { /* render the options page */ },
  {acl: {
    type: 'private', 
    strict: true
  }}
);

This way of adding options may remind one of how the ui plugin is used. Indeed the registration process is roughly the same, except for the recognized options.

I also introduced the strictness parameter earlier. For our option page, we only want the owner to change parameter and never should it be a user. Since we should never change this access type, it makes sense to set a strict access node.

Defining an Action
Of course, this option page will be used to set options. For this purpose, we will use a Yusef Action. Actions are only associated with an access type (level) and are not considered as resources. The following code sets an action for the options page:
Yusef.registerUniteAction
(
  'set-options',
  function (connection) { /* handle the [URL=http://www.cgisecurity.com/xss-faq.html#vendor]user input[/URL] here */ },
  { acl: { 
      level: Yusef.plugins.acl.getAccessTypes().private
  }}
);

We may further wonder how an action can be made available to public or to limited users depending on whether the corresponding section access. One possible way is to set the level to public and check in the action handler whether the section is accessible. For this we can use the hasAccess function of acl, which takes as arguments the connection, and optionally the section and the path within the section. The following code demonstrates this, allowing for only allowed users to save the options:
Yusef.registerUniteActionListener("set-options", 
  function(connection)
  {
     /* Do we have access to the "option" section ? */
     if (!Yusef.plugins.acl.hasAccess(connection))
     {
        /* bad guy. In the actual code, you may want to record this event in some log */
        return false;
     }
  
     /* Clearance check OK; proceed with actually saving the options */
     /* ... */
  
  }, { "acl": Yusef.plugins.acl.getAccessTypes().public });


Changing the Access Type

We defined the strictness of an access node earlier, but nothing was said about how to actually change the access type. For this purpose, Yusef.acl provides functions to read and write an access node: setAccessNode, getAccessNode and hasAccess. These respectively define the access node of a resource, retrieve the current access node of a resource, and determine whether the user has access to a resource. These functions are defined as follows:
setAccessNode = function( serviceWidePath, type, strict )

  • serviceWidePath: The path to the resource relative to the application root, including a leading '/'.
  • type: A string representing the access type ('private', 'public', 'limited).
  • strict: The strictness of the access node.
  • Returns true if the access node could be set, as requested or false otherwise.

getAccessNode = function( connection, section, path )

  • connection: The connection from which the resource path is to be retrieved.
  • section: (optional) The application section of the resource.
  • path: (optional) The path under the application section of the resource.
  • Returns the function returns the accessNode corresponding to the path.

hasAccess = function( connection, section, path )

  • Arguments have the same definition as for getAccessNode.
  • Returns true if the user has access to the resource


While most of the parameters are clear, the actual meaning of the path to the resource may be discussed. The most obvious definition is the url to an actual page of the application. However, some applications (e.g. like Fridge) use the index page for various purposes (e.g. displaying user posts and application settings). However, posting new messages, deleting messages, and setting the maximum number of messages can require very different access. In such case, "virtual" urls can be associated to features requiring different security tokens. For example, using access nodes over /security/post, /security/delete and /security/options would solve the problem.

Integration with the UI

In this last section, we get back to where we started this post, and study how the acl and ui plugins are integrated. The UI plugin has indeed some interaction with acl: when a new user navigates to a limited page, a message is shown requiring him/her to provide a password. Another integration, provided in the right side of the default template, allows the owner to change the access type of a page.

To provide ui with these features, acl registers the following actions:
  • Yusef_plugins_acl.unlock: checks that the password provided by the user is right. In that case the user goes from "public" privileges to "limited" ones.
  • plugins.acl.actions.change: allows the owner to set the access type for the current page

As with any action, the proper unite-action and unite-nonce fields must be set. The other fields needed for these features can be found in the main.html file of default ui template.

Debugging Yusef ApplicationsAre you the person I spoke with, last time?

Write a comment

New comments have been disabled for this post.