Appendix B: Description of security features

Enano includes a number of features designed to go above and beyond what would normally be used to protect a site against attacks from crackers. Some of these features are outlined below.

SQL parser

Enano's database abstraction layer uses an honest-to-goodness SQL query parser. Before a query is sent to MySQL, the parser checks it for mis-matched quotes, query stacking (sending more than one query at a time), and the comment marker (--) in the middle of a query. If any of these checks fails, Enano will exit with an error and log the query. If you see a message saying that Enano has caught a SQL injection attempt, you have likely found a SQL injection vulnerability in Enano. This is because no query ever sent to the DBAL should ever have mismatched quotes, query stacking, or comments within the query itself.

AES encryption

The biggest security feature in Enano is its ability to encrypt strings using the Advanced Encryption Standard, or the Rijndael cipher. By default Enano uses 192-bit encryption and 128-bit block sizes, though you can change these parameters before you start the Enano installation. All passwords and session keys are encrypted with AES, with the master key being stored in config.php. The philosophy behind this is that if the site security is ever compromised, it is likely to be either the filesystem OR the database - not both. By storing the lock and the key in different places, Enano aims to make reversible password encryption as secure as possible.

Another reason AES is used to encrypt passwords is our decision to favor network-level security over security on the server side only. Most web applications either send passwords in plaintext or run a one-way hash (like MD5 or SHA1) on the password before sending it. The former is insecure because anyone who has access to a router or gateway in between the client and the server can steal the password. The latter is insecure because if an attacker merely has a user's password hash, they can gain access to the account. Using AES ensures that the person has the "real" version of their password.

Granted, with enough expertise, an attacker can still listen in on a user's password when Enano transmits it, though this is much harder than it is to do with traditional challenge-response authentication. This weakness is closed in Enano 1.1.3, which provides users with the option of using a Diffie-Hellman key exchange to generate the AES encryption key.

Enano's logon process works as follows:

  1. The user requests a login form
  2. Enano generates and stores an encryption key and sends the key to the user, hex-encoded
  3. The user inputs his password. The MD5 hash of the key is then calculated, and the hash replaces the original key in RAM.
  4. The form, containing the username, encrypted password, MD5 hash of the AES key, and an MD5 challenge string (for a backup) is sent
  5. The server looks at the MD5 hash of the key and iterates through all cached encryption keys until the key with the same hash is found
  6. The key is retrieved from the database and used to decrypt the password.
  7. The password in the database is then decrypted
  8. If they match, and if the MD5 challenge validates, the user is logged on.
  9. In either case, the logon attempt is logged.

Changes to password storage in Caoineag

Starting with Enano 1.1.6, passwords are no longer stored using reversible decryption. The Enano team decided to do this because it provided too much of an opportunity should the entire server be compromised. Instead, HMAC is used to salt passwords over the SHA1 hash function, and the salt and hash are stored in the database.

This impacts developers because it provides a breaking change in the way external authentication can be handled by plugins. Since no pure form of the password is ever available to Enano except during the logon process, compromise of a site will keep passwords fully secure; however, plugins that simply hash the password before sending it over the Internet will no longer be able to do this. They must use AES, Diffie-Hellman, or transfer the password in plaintext.

If you're a developer, the easiest way to do this is to use the Javascript login API and require authentication to USER_LEVEL_CHPREF (for something all normal users can do), or USER_LEVEL_MOD or USER_LEVEL_ADMIN (for something restricted to moderators and administrators). Enano 1.1.6 and later allow the entire page to be redrawn to use the newly obtained session key, meaning your AJAX-based applet will be able to continue its action right where it left off after the login process completes successfully.

Developers can learn how to use Live Re-Auth.

High-privilege session keys

In Enano, each user has a numerical user level, which determines what that user is allowed to do on the site. A user level of 1 means that the user is a guest. User level 2 is special because it is the level at which all logged-in users normally operate. Any access higher than level 2 requires re-authentication.

User level 3 is used when a user wants to change his or her e-mail address and/or password. They are asked to re-authenticate to ensure against fraudulent account updates.

User level 5 means that the user is a moderator. Currently the moderator position does not have very many extra benefits, other than having tools to remove spam and off-topic or inappropriate content.

Lastly, user level 9 means that the user is an administrator. If your user level is set to 9, you are unconditionally allowed to edit access control lists, access the administration panel, and basically bypass anything security-related. So, for UNIX and Linux geeks, a user account with level 9 access essentially gives you root privileges. If a user has a user level of 9, they are allowed to enable PHP to be embedded into pages, even if it was disabled during installation.

Your session key for level 2 or lower is always stored in a cookie. When you re-authenticate, your session key is sent through the URL on the "auth" parameter. This serves as an additional reminder that you have elevated privileges.

For administrators, some pages can only be loaded if you have an elevated authentication key in effect. This includes the administration panel, the sidebar editor, the upgrade script, and several plugins' installation pages.

High-privilege session keys last 15 minutes, and are renewed on each Enano page request made with an elevated privilege session key. This includes requests made by AJAX applets. For example, if you open the administration panel, load a page within the admin panel 10 minutes later, and save your changes 10 minutes after that, your key won't expire. However, if you spend more than 15 minutes without loading any pages using your high-privilege key, and keep-alive is turned off, you will be denied access on the next page load.

Password strength evaluation

Enano features the ability to score passwords based on complexity. You can require passwords to get a minimum complexity score before a user's registration will be accepted, to reduce your chances of an account getting compromised. To enable password strength scoring, browse to General → General Configuration in the administration panel, check "Enable password strength scoring", and enter a minimum score (-1 is usually good).

Encrypting login details

Please note: The following section applies only to Enano 1.1.x, specifically Enano 1.1.3 and later.

The "Encrypt My Details" option allows you to choose an extra layer of security on top of Enano's normal protection on your password as it is transmitted across the Internet. This is done through a process known as a Diffie-Hellman key exchange.

The Diffie-Hellman key exchange protocol, named for the two mathematicians that invented it, is a way to generate a cryptographic key and communicate it securely, even if an attacker is picking up all information as it is being transmitted. With a Diffie-Hellman key exchange, the encryption key that protects your password is never sent "across the wire." This ensures that even if an attacker is using techniques such as packet sniffing to record your login, they cannot decrypt your password.

With encryption at this level, unfortunately, comes performance concerns. We spent a great deal of time optimizing Enano's login process, and have gotten everything down to the step of performing the high-precision math required to generate the final encryption keys. This has been unit-tested in a wide array of browsers, with the most focus being dedicated to the generation of browsers consisting of Google Chrome 2.0, Firefox 3.5, Safari 4.0, Internet Explorer 8.0, and Opera 9 and 10. We've found that these browsers work very fast with Enano: they typically take less than a second to perform encryption. This is comparable with about 2-4 seconds on the previous generation of browsers such as Firefox 3.0 and Google Chrome 1.0. Users of older hardware will notice a greater delay, but nothing greater than about 6 seconds. We've also noted that strong encryption is working under iPhone Safari 3.0, benchmarking at about 4 seconds.

Remember that Enano can't do public key cryptography; that is, it is not possible to ensure that you aren't being victim to a man-in-the-middle attack (that is, someone is modifying your traffic). You can't implement that in HTTP; the only way to do it is through HTTPS. Diffie-Hellman is very secure against a listener who cannot modify your traffic, but significantly weaker if an attacker gains the ability to modify requests and responses.

Important: if you are asked to stop the script due to it being unresponsive, allow the script to continue. Most major web browsers will offer to stop running scripts that perform a lot of calculations in a very short amount of time, since this can sometimes indicate faulty code that leads to infinite loops. If you stop the script execution, you'll need to start the login process over.

As strong encryption does not work under Internet Explorer 6 and 7 or iPhone Safari for iPhone OS 1.x and 2.x, support for it has been disabled for those versions.

Security advantages of strong encryption

There are certain things that strong encryption protects you against, and there are certain things that it can't protect from.

Unless your website uses SSL, there is no way for Enano to protect against direct session hijacking by way of cookie theft. The session key Enano issues once your login is successful can potentially be used by anybody that convince the server that it's receiving packets from your IP address.

What encryption does protect you from, however, is break-once-run-everywhere (BORE) attacks. This is done in two ways. First, encrypted traffic used to log you on is valid only on the Enano site you're logging into, and the encryption keys are used once and then thrown out. This means that it is impossible for someone who is listening in on your connection to replay your login attempt at a later date. The server simply doesn't have the private key that it needs in order to decrypt your password.

Moreover, strong encryption enables Enano to require your real password in order to log on. Many other websites simply MD5-hash your password before sending it across the Internet. This does nothing for security: your password's MD5 hash is now just as powerful as the password itself! By requiring your real password, Enano ensures that if you use the same password on another website, and the other website's database is cracked giving the attacker access to a hashed version of your password, they cannot use that to compromise your account. Enano also salts passwords stored in its database using HMAC-SHA1 - meaning that if your own Enano website is compromised, the salted password is useless elsewhere.

To summarize, the primary benefit of using strong encryption is that any breach of security, be it on your Enano website or elsewhere, becomes much more difficult to spread around.

Remember that no level of encryption is a substitute for using strong and varied passwords. The best way to protect your identity is to never re-use passwords.