Tuesday, November 29, 2011
Thoughts on Liferay Portal and Security: Part One
My early involvement with Liferay started back in the days of Liferay 2.1 when I created an integration with Netegrity Siteminder. Several versions later, I also integrated with XACML Entitlements Management products from Oracle and Securent (now Cisco). So security functionality has been part of my thought process very early on. Throughout the lifecycle of Liferay I have performed other activities such as being the first customer to get Liferay running on Azul Systems which is a specialized Java appliance that has 768 cache coherent cores.
I had the opportunity to perform the first security review of Liferay by using a now defunct binary-analysis tool from a vendor then known as AppScan. In order to be fair to the community, I will be updating my security analysis of Liferay in two parts, where the first part is to look at the security features of the product and to point out deficiencies I think need to be addressed and to at a later date (over the Christmas break) use two commercial static analysis tools to understand whether Liferay code was written securely.
Without further ado, here are my reactions of looking at the latest version of Liferay through the lens of security:
Enabling/Disabling users: Currently this is represented by a boolean value which indicates that you are either disabled or enabled. I believe that this should change to incorporate reasons for disabling. For example, if an account was disabled for reasons of spam/abuse, that is different than an administrator simply locking an account because the user is on vacation.
Identifiers: Many Liferay objects such as user, group, organization, etc leverage the Liferay counter model which provides an auto-incrementing value that is highly predictable. A better approach to such primary keys would be to support the notion of GUIDs which are more cluster-friendly and less predictable in nature. We no longer live in a world where disk space is expensive, so a few additional bytes won't hurt performance but could increase security.
IDs vs credentials: User identifiers as primary keys into databases should be kept private. There are many places within Liferay especially when interacting via remote services where this identifier is exposed. One optimization would be to have a servlet filter that allows for public credentials to travel over the wire and then be transformed into the private key implementation.
Siteminder: The traditional way to integrate with Siteminder was to either accept a cookie/header or to use the Siteminder SDK. Depending on how the former is deployed, there may be security gaps especially if you deployed a Siteminder agent on the web tier but not the application tier. Anyway, Siteminder like most products is moving away from proprietary SDKs to open standards such as SAML. There needs to be a way of integrating container-based SAML support into the Liferay security model.
Sanitizer: Liferay provides the ability to sanitize content via its com.liferay.portal.kernel.sanitizer.Sanitizer. This needs to be made more configurable (coarse and fine) and integrated with the OWASP ESAPI.
OpenID I am a big fan of OpenID and oAuth but these protocols do work over insecure (non-SSL) channels and therefore believe an administrator should be able to filter out ones provided by users that don't support SSL. Alternatively, for higher assurance sites using these protocols, you should also be able to specify a whitelist of providers.
Administrator: There needs to be two different types of administrators. Administrators that can create users and administrators that can create other administrators. You should also have the ability to restrict where adminstrator-level accounts can access the environment from. There would be something strange if an administrator who happens to be currently out of office accessing a bank site running Liferay from Iraq at midnight.
User Management: Liferay allows the ability for an administrator to open another browser window and browse the site as though you were the user. Imagine a scenario where you are using this on a company Intranet site and had a payroll portlet. There needs to be a way of specifying in the portlet's security model that this can only be seen by the real user and not via impersonation.
ServiceBuilder: This utility is used to describe a model's class and attributes. What would be a better place to describe the requirements for validation than here? Imagine the ability to tag an attribute with a Regular Expression that could provide validation capabilities. ServiceBuilder could ideally do several things with this information ranging from creating the appropriate database constraints to providing consistent validation whether accessed through portal or remote means.
Resources and Permissions: Liferay has a wonderful permissions framework that can handle many finer-grained authorization decisions but this still has certain gaps. The first gap is that you have to add resources into the permissions system by calling an API. In the scenario where you may want to implement something analogous to an XACML obligation, this model will require you to implement a new portal hook for each object type that only calls the addResources method so that you can then integrate it with a subsequent permissions call. For example, if you wanted to use the permissions framework to create a way for select portlets to be "available" during specified hours. An alternative way would be to allow for a given portlet/resource to support description of permissions in an extensible manner via its XML configuration.
Anyway, there are probably other things that I have not yet thought about but probably could be weaknesses, so all disclaimers apply. With that being said, you should feel confident in the fact that while no portal is ever 100% secure, there is a vibrant community looking out for your best interests when it comes to security and that Liferay is leading the pack in this regard. Something that cannot be said of many commercial implementations. Take note Gartner and Forrester...
Links to this post: