Securing Liferay Chapter 2: Liferay's configuration

You probably know the basic installation instructions for Liferay Bundles: „unzip and run startup.sh“ - with this you get to a working Liferay installation in a minute. It will run with all defaults - which might not be what you want in production.

This is part 2 of a series. Start with part 1 for "Introduction, Basics and Operating System Level", then continue here and check if more chapters are already available.

What Configuration?

As we've covered the Operating System Basics and the appserver with Liferay is running as an unprivileged user, let's check Liferay's configuration. Some of Liferay's configuration is done on the UI layer and gets persisted to the database. As the UI options naturally are spread all over the administrative UI, let's put this to the side for now. There's another resource that provides quicker ROI:

portal.properties

First of all: As a motivated System Administrator, you should have access to portal.properties already. It's well packaged (so that you don't accidentally change it) in Liferay's WEB-INF/lib/portal-impl.jar. Go ahead, extract it and keep it around. Then read it - yes: I actually recommend to read it. It's roughly 10.000 lines of configuration options, commented optional configuration as well as a lot of documentation for the individual configuration options.

You can also get hold of a HTML rendering of this file on the documentation server if you don't like the formatting of portal.properties. It might be easier for the eye to read.

Do you need to read it line-by-line? No. There are large sections, that you can easily "page-down" through. But if you have a broad idea of the content, you'll get a lot of ideas about Liferay's configurability. In fact, you might find features that you never knew to be in Liferay. I have learnt a lot about Liferay's features this way. And I have found some convenience options, that I'll add to every instance that I maintain.

(If you read it now and come back once you're done: I promise that I'll be still here when you come back)

...

...

...

...

...

...

No, really. Go read it.

...

...

...

...

...

...

...

What now?

Wasn't that an amazing read? What did you learn that you didn't know of?

Now that you've been through the file at least once, you might want to go through it again - now searching for specific values. Try the following search terms (and again, some of the places you can page-down through). Note, by design some are only partial words (e.g. in order to search for "security" or "secure", just search "secur")

  • password
  • encrypt
  • hash
  • restrict
  • secur
  • auth
  • timeout
  • servlet.filter
  • deploy
  • register
  • https

And when you're done with this, you probably want me to name the settings that you must set in order to get the "secure" certification for your configuration. Right?

Well, unfortunately I won't and I can't: What adds security for one ruins a feature for somebody else. You're totally required to do your homework - I can just point you to the options that you have. I think I forgot to mention earlier that security is hard work, but you probably knew this. This is part of the work. (oh, and please suggest your favorite settings that you keep an eye on)

If you don't like to do this work by yourself: My colleagues and I are available for rent ;). We'll still ask a lot of uncomfortable questions though. Ok, pun aside, I'll give you a few places to start:

Starting places

Yes, I'll give you a few. You'll have to promise though, that you'll view these as starting points. Everybody's system is different and I don't claim these to be complete (in fact, I'm keeping some options back, giving you the opportunity to shine in the comments;) )

jdbc.default.password: Do you like cleartext passwords to be available on disk, for anybody opening that file? Probably not. Liferay's default configuration uses the manual database configuration with driver, URL, name and password. However, you can also utilize JNDI and just replace the four classic configuration lines with a single entry on jdbc.default.jndi.name. Look it up, now you'll need to configure your application server to make the JNDI connection available to Liferay, and Liferay doesn't have a chance to know the connection password. On Tomcat this AFAIK still means that you have a configuration file with the password in clear text, but that's in tomcat's realm, no longer with Liferay. (Correct me if I'm wrong)

company.security.strangers.*: If you are running an intranet portal, you probably don't want random users to generate new accounts on your portal - by default they can. And if your content administrators just protect content for logged-in users, this can poke some holes.

portal.security.manager.strategy: If you're running 3rd party plugins from marketplace or other developers. If you mandate that plugins have security manager (PACL) enabled - you might want to enforce these settings.

ldap.*: It's easier to move your LDAP configuration around and configure different servers, if it's just a bunch of lines in portal-ext.properties. This might rather be convenience than security, but nailing the login process makes sure that only the right people can log in (and you can test the setup, move it around without typos etc)

*.auth.enabled: Determine the kinds of login that you allow on your system. Do you want to allow OpenID? Enable Facebook?

passwords.encryption.algorithm: On 6.2 Liferay uses a pretty good default. If you're running an older version and keep the hashed passwords in Liferay's database (as opposed to LDAP), you might want to know other options. Should your user database ever get loose, you don't want the hashes to be easy to brute-force.

default.admin.*: I don't like default user accounts, in any system. Even though Liferay comes with its own setup wizard where you can configure the admin user, you shouldn't timeout the session - otherwise you'll find that the default password has been taken from here (ever had a phone ringing while you did administration work? Or worse, a twitter notification or a squirrel in front of your office?)

com.liferay.portal.servlet.filters.*: Various filters that are active by default. If they refer to a product name that you don't know, most likely they can be disabled (e.g. for the SSO options that Liferay supports, you can disable either all or all but the one that you're using)

Take these settings as your starting point. Go further through the file and check what's around these settings. If you have your own favorite configurations that must not miss in this list (hint: it's not complete), consider adding them to the comments on this article. This way everybody gains that knowledge.

User Permissions

New users in Liferay, by default, are members of the roles "User" and "Power User". You can remove the "Power User" association, but should keep "User" as this is a sign that they're authenticated. However, this role comes with quite a lot of permissions. If they match your requirements - I don't know. You should inspect the list of features that they enable. Decide if your users should be able to maintain their own personal sites: This might open you up to malice behaviour if they can add custom administrative portlets to their sites. Liferay's portlets are typically safe and can't be added to personal sites, but you might have more than just the stock portlets.

Not to mention that your helpdesk might be thankful if they don't have to repair your user's personal sites every now and then when they deleted important portlets from their pages.

Do you <script>trust();</script> your content authors?

AntiSamy LogoIf you get what the headline implies: Answer the question. If you do trust them, continue on the next chapter. If you don't get the headline or don't trust your authors: Install AntiSamy (CE or EE) which will "make them trustable" by applying the OWASP rules to their content and eliminating potentially dangerous (scripting) content. You can also implement this functionality yourself by implementing com.liferay.portal.kernel.sanitizer.Sanitizer and configure sanitizer.impl in portal-ext.properties. When you implement this yourself, you can allow certain content that otherwise would be blocked (like embedding content from whitelisted external sites - like youtube - etc)

Portlets

You can disable quite a lot of portlets that Liferay delivers out-of-the-box if you don't need them. In the unlikely event of a loss in cabin pressure (e.g. in case one of them has security-related issues), you don't even have them available. When you choose a product like Liferay, you want it to have as many features as possible. If you want to lock down the installation, you want as few of the unused features being exploitable as possible. Careful: This might annoy your business users that expect to have the full feature set of Liferay available to them.

Portal Instances

I've seen a neat use of portal instances once. While instances are positioned for multi-tenancy, I personally don't really like all of the tenants to be sharing one portal/appserver. However, there's a nice aspect that rarely gets exploited: Only the default instance has access to the server level administration - e.g. only there you can install new portlets, trigger reindexing or garbage collection. When you use your default instance purely for administration and one extra instance for all content, none of your content administrators (not even those with portal-wide administrator roles) will be able to access these features and install server side code through Liferay's UI.

Future chapters

  • Fixing the port 8080 issues (and more HTTP-level issues, like https)
  • more Tomcat lockdown
  • a new episode of Radio Liferay on Security

...coming soon...

Looking forward to see some of you next week at Devcon. Remember to sign up for the community meetup.