security

Please Stop: Securing User Accounts with mySQL's Password() Function...

I tweeted a week or so ago:  Please stop using mySQL's password() function.  I had good reason for doing so - the legacy software I've been assigned to maintain until I can help with the new rev has a password schema that is based entirely on mySQL's password function as the hash strategy for storing user-account passwords in the database. As developers, we should be getting that uncomfortable, squishy, feeling whenever we read about another corporate hack event, one that exposed gazillions of user accounts to the ether, and zomg, we even got their passwords!!!

There are really only two, well three, ways to store user account passwords within a software system.  You can store them as clear-text, (legitimate depending on your system design and needs), encrypted, or hashed.

Most of us LAMP developers choose the hash method - it's easier since the PHP function uses the same algorithm as the mySQL password function and, bonus, we also have "plausible deniability" when it comes to risk-exposure because hashing is a one-way encryption -- we can't tell you what your password is because we don't know.

Encrypting a password takes a couple more steps in the code to accomplish, but the bonus here is that you can reverse the encryption and generate the user's original password from the scramble.  It poses only a lower "comfort" level for business rules since it can be "cracked" eliminating the soft comfy blanket "plausible deniability" brought you by hashing.

Hashed passwords can be cracked.  If you're using mySQL's password function, then they can be hacked, too.

What?!?

If your database ever exposes your user's passwords, all a hacker would see is a 41-byte string (assuming mySQL 4.1 or later)  of random characters.  However, the algorithm used to generate this 41-byte string is fairly well known.  I googled the process last week and I found API's written in everything from Javascript to PHP that provide the same functionality - taking a cleartext password and applying the algorithm to generate the 41-byte hashed string.

This is how we, as developers, validate users logging into our systems.  We obtain the user's clear-text password using an HTML form and, more often than not, we just shoot that clear-text over the wire from the client machine to the server, where the server uses an on-the-fly hashing to compare the value against the stored value in the db:

[cc lang='php' ]

if (md5($userPassword) == $dbResult['password']) {

[/cc]

Since we're comparing hash-values and not passwords, we somehow feel safer and more secure, right?  I mean, we're not really dealing with clear text, so it must be good...

The PHP function md5 is a fast hashing algorithm.  The PHP website itself recommends NOT using md5 as a method of securing passwords because of this very reason.  Hackers will use a brute-force approach to cracking your hashed password value - usually against a dictionary specifically collated for this purpose - and can break your hash in a matter of seconds.

Consider if I've obtained the password hash for a user account, all I need to do is to run my password cracker, with it's huge dictionary of common passwords, through a simple md5 algorithm, and compare the output value against the hash I hacked off your system.  I guarantee you, for most user accounts, I'll get the 'ding - the turkey's done!' chime within seconds.

Good user-account security takes effort.  Not a lot of effort; we're only talking about a couple more lines of code, here.  But some effort.  What I'm proposing isn't going to turn your user-authentication design into an electronic Ft. Knox.  But it will make your account harder to crack than some other poor sucker's website.

5 Steps to Better Password Security:

1. Stop sending passwords in cleartext over the wire.  

If you can't use an SSL connection back to your server, then at least encrypt the password client side using Javascript and return the encrypted value back with your form submit.  Something is better nothing in this case.  If you're sending your passwords clear-text from the login form back to the server, (and you'd be amazed at how many websites do this!), then you're begging to be hacked.

2. crypt() is your friend

crypt() is a PHP function based on the mcrypt library and is part of the current PHP core.  So there's no good reason for you to not use it.  Others will argue for the hash() function because it offers more encryption algorithms than does crypt().  While the hash() extension is bundled with PHP, it has to be added at compile time -- no guarantees that hash() will be available to you.

3. Pick a good salt

The Salt is the second parameter to the crypt function and is applied during the hash to prevent your hash from appearing in a rainbow table of pre-computed hashes.  Don't store your salt in your database tables either.  Store it outside of directory root.  I like to use long sentences for my salts that are easy to remember (for me) but make little sense to anyone else.  ('My ex-wife used to make lemon-flavored chicken that tasted like hammered owl shit.')

4. crypt(Blowfish > SHA1 > md5) > md5() = Password()

If you're going to go to the trouble of using the crypt library to secure your user passwords, then at least use the Blowfish algorithm.  According to the documentation, it's computationally more intensive than SHA1 or MD5 but it scales.  For extreme paranoia, consider using SHA256 or SHA512.  If you've got the room to store these passwords, and the CPU cycles to process, then they're your best bet using this schema.

5. Hash the hash

There's nothing that prevents you from hashing the hash.  First pass, process the password using SHA1 and pass that hash back into crypt using Blowfish.  Two or three-pass encryption is common enough and adds an extra step of complexity that makes your system less desirable to hackers.

 

Remember, crypt is still a one-way hashing algorithm just like the mySQL password().  Earlier in the article I mentioned encrypting passwords as a means of securing them.  In this context, encrypting a password (as opposed to hashing as password) implies decryption -- that you'll be able to reconstruct the original password from the encrypted output.

That, friends, is a blog post for another day.

Online Cloud Storage...Which one?

In a recent article, I wrote about cloud storage to use for my source-code repository.  I chose ZumoDrive as the tool to implement this because it allowed filesystem level access to my files from the desktop.  Or, in other words, my desktop sees the ZumoDrive like another physical device attached to my computer. However, in actually using ZumoDrive, I noticed some ... features ... that I wasn't too pleased with.  Instead of capping on just ZumoDrive, I thought I'd offer a narrow perspective on the capabilities and ... features ... of some of the more popular online cloud-based storage options.

My selection process was based on simply whether or not I could use the storage from my Mac.  Let's get started...

The first system tested was Memopal -- this solution is available on all platforms, (Windows, Linux, Mac, Android, iPhone), and offers 2Gb of free storage.  It advertises itself as "online backup and storage" as it archives your files in real-time to their remote servers.

You can browse any of your files online, using a web-browser, and you can also share these files with other users.  Memopal allows transfers of files that are larger than 1Gb, so using this service as a means to copy files to other users, because you can't send large attachments though email, make this a handy solution.

What's also amazing is that you can get 200Gb for only $49 per year.

What's not so amazing is that it doesn't provide you with desktop level access to your files so you can't use the offline storage as a real-time disk file system.  For my needs and purposes, I'm going to pass and un-install the product.

I have been a .mac (or .me) account owner since 2007 and have witnessed several upgrades to the service.  I was in the process of dumping my me.com account when Apple suddenly extended my account until June 30, 2012 in anticipation of the release of their iCloud offering.

The iDisk, as it's referred to via your mobile-me account, is slightly more than 15Gb of online storage which used to cost you $99/year.  (You got other stuff besides the storage which supposedly made it a "deal", but Apple has been forced to re-price their offerings in order to remain strategically competitive with other cloud vendors.)  The iDisk is configurable from your System Preferences menu and, if you're one of the account holders at the time Apple froze the offering, you can no longer upgrade or increase your storage capacity.  What you had is what you have until the iCloud becomes available.

What's good about this storage is that it's accessible as a mount-point (file system access as a device drive) to your system which means you an use it finder, or through any application, to access your files.  It's totally transparent as a remote device.  I also like that I have to manually mount the device to access it so there's never any background "sync" happening to slow my system down when I don't need it.

The downside is the bandwidth limitation of 200Gb of data transfer per month.  If I'm doing a lot of development, I'd imagine I could hit that pretty quickly just checking-in, and then creating and modifying the existing code base.  So I've never tried to use my iDisk for anything other than storing static documents that I don't need clogging up my physical devices.

Because of the bandwidth limitation, Mobile-Me does not satisfy my requirements.

ZumoDrive is the software I initially chose to use as my cloud-storage choice for my source-code control.  ZumoDrive is also the reason why I am writing this article, wishing I had done my due-dilligence in evaluating the software before committing (svn pun) to it.

ZumoDrive offers you 1Gb of free storage which is easily expandable to 2Gb once you complete the "belts" in their "dojo".  Cute.  Basically a test-drive through the product, training in the Dojo advances you through the belts until your max your training at black-belt and you've doubled your storage to 2Gb.

ZumoDrive is software you download and install.  It's available on all desktop and mobile platforms.  ZumoDrive mounts on your desktop as a virtual drive, which meets our purposes of remote file-system storage.  Unfortunately, ZumoDrive caches a copy of your file(s) on your local drive and then updates the remote drive when not in use.  Like, when you're playing World-of-Warcraft and need the network bandwidth because, you know, it's not already laggy enough in capital cities.

If you've followed my previous tutorial and created a TrueCrypt container on your cloud drive, then the real downside of this system makes itself readily apparent.  Uploading a 500Mb file to the server at (average speed) 77Kb/sec is going to take a LONG time.  Changing the cache options to minimize the amount of diskspace stored locally didn't impact this -- the software still sees a single, 500Mb file.

While I love the concept of ZumoDrive -- MobileMe without the bandwidth constraints -- the local caching of the TrueCrypt volume murders the concept since it's doesn't see the files within the TrueCrypt container.

SugarSync is an online cloud storage system that offers a 30-day free trial.  You can get 30Gb of online cloud storage for $5/month or $50/year.  They have a 250Gb plan for $250/year which is sort of funny when you look at what Memopal was charging: $50 for 200Gb...

I'm not going to incur another monthly charge for online storage so, to be honest, I didn't even bother to download and install the product for evaluation.

TeamDrive offers 2Gb of free cloud storage.  From reviewing the product on the website, I knew it wouldn't meet my requirements, but there were enough enticements to the feature-set that I went ahead and downloaded and installed the 100Mb file anyway.  TeamDrive is accessed through a custom-application that's finder-like in it's UX.  You can also access the application my clicking on the relevant icon in the menubar.  TeamDrive offers collaboration and synchronization as it's main features.

The UX is intuitive although window's-like.  Since TeamDrive is primarily collaboration software, it keeps track of the users who are in your team.  Although I didn't think much of the product for what I need, I was encouraged to evaluate the offering because it had a feature I'd not seen before -- the ability to create and host your own TeamDrive server.

I've been using Dropbox for over a year now.  It's my primary means of transferring files between home and work.  I also like the fact that 1Password uses it automagically to synchronize itself.  Dropbox offers 2Gb of free cloud storage that is accessible from pretty much every known appliance available on the market today.  Dropbox provides you with a file-system mount point so that you can access your files via Finder making it perfect for what I need.

The only downside, for me, is that I depend on Dropbox for file storage for other things such that my available bandwidth is only about a 500Mb.  The upgrade costs are prohibitively expensive, especially when compared with other offerings in the industry.  Sorry, Dropbox, but $200/year for 100Gb is not a value-add.

The final note, for DropBox, is that it, too, views an encrypted file container as a single file.  Dropbox's upload/synchronization speed was even worse than ZumoDrive's at 55K/sec.

I also have an Amazon Cloud account -- which is 20Gb of free storage -- because I use Amazon's MP3 cloud on my Android device.  I mention it here because of the phenomenal amount of storage that you get for FREE.  I can only access my cloud storage through the web, which is ok since all I'm storing there are my MP3 files that I've downloaded (DRM Free - hear that, Apple?) from their music service. Unfortunately, I can't access the storage from my desktop...

Other Mentions:

I looked at these products but didn't bother with the evaluation since I could read, from the product descriptions, that they would not satisfy my requirements.

idrive.com -- 5Gb basic (free) solution limited to only back-up and recovery.

syncplicity.com - web-based back-up and recovery tool.  Free, but limited to 2-computer access and 2Gb storage.

spideroak.com - pretty much web-based b&r and file sharing through the web ux.

Conclusions

What I want to do just isn't possible at the current time because of restrictions of my DSL and the way cloud services view a TrueCrypt container.  I've got a pretty good working overview of what's available and I explored a lot of solutions that were pretty damn exciting.  I also think that we're going to see the cloud marketplace evolve rapidly and those companies which are charging significant amounts per megabyte are going to have to rethink their pricing strategies or risk becoming fossil fuel.

I'm also excited by what Apple will bring to the table with iCloud -- I think that we'll be able to have file-system level access to our cloud storage but I'm also sure that the same limitations will apply for synchronization...

Secure Access to Cloud-based Source-Code

I've had this idea for about a week now -- I want to store my working source-code tree in the cloud, securely, so that I can access it from my machine at work, or from home.  I use a laptop at work as my primary machine -- which is cool -- but I really hate lugging the damn thing back-and-forth from work to home. In my mind, it introduces risk - shoving a laptop into a backpack and trundling 70 or so miles (one-way) just doesn't seem, to me, to be the best way to treat delicate electronics, even if said device was designed to be portable.  There's also the additional liability of theft or loss of the device.

Like most geeks, my home machine makes a far better development environment because it has significantly more display real-estate, more memory, and faster everything else.  I don't have to hunt for a spare power receptacle to plug the laptop into, or work off the kitchen table because my desk is already at capacity.

So I came up with the idea (and I'm not claiming this to be original - but it does work) that if I could store my source code in the cloud, then all I'd need is a duplicate operating environment (apache, mysql and the db contents, etc.) while I ran my development source from the cloud, pushing it to the stage-server when necessary, thereby always maintaining the code in a consistent state across platforms.

I need the repository to be stored under subversion, and I want really decent encryption so that if the account gets hacked, my code isn't exposed.  (Protect corporate assets.)

Oh, and I want it to be free.   :-)

And to be large enough to store my entire project.  (I like CloudApp and DropBox, but I don't feel they offer either enough space for what I need to do, or the ability to access the remote "device" as a filesystem.)  Here we go...

I decided to use a service called ZumoDrive for my cloud storage simply because they offer 2Gb of mountable file storage.  Unlike others, this storage is visible as a mounted drive on your desktop.  It's also compatible with Mac OS X, Linux, Windows, and mobile devices (Android, iPhone and Palm Pre).

Go to their website - I've linked it above - and download the appropriate file -- they pretty much walk you though every process -- and install the file on your machine.  On my Mac, the install requires only 4.7Mb of disk space.  Sweet.  Once installed, you'll be asked to create an account or log in to an existing account.

I first installed this application on my desktop machine.  I created a login/password using my favorite account management tool, 1Password, and I chose a randomly-generated 16-bit password.  As an aside, the more I use 1Password, the more I rely on their password-generator.  I'm breaking the mold of the rotating-three passwords and using something that's both non-intuitive and random to protect my accounts.

Once I've created an account, and logged-in to the account, I'm now in the Zumo landing page, or what they term the "Dojo".  Initially, Zumo offers you 1Gb of free storage but if you take an extra couple of minutes to run through their tutorial and examples, they'll quickly bump you (promoting your account in "belts") to the maximum storage freely available of 2Gb.  Sweet.

What you now should have is a mounted drive on your desktop that looks like any of the other connected devices.  This virtual drive is accessed like any other drive which allows you full file-system management to the device.  (You can copy and delete files and stuff.)

Before we do anything, we want to prepare the device.  I was wondering if the data you stored on the cloud device was secure so I searched-for and found this blog post from Zumo which basically states:

The file being uploaded is transferred to the ZumoDrive server which is hosted by Amazon's EC2 (Elastic Compute Cloud).  It is done via 256-bit SSL encryption.  SSL is the same type of encryption used when you log into your bank's secure website.  The EC2 is the workhorse.  It's the liaison between the client on your computer and the ZumoDrive datacenter (which is hosted by Amazon S3; more on this below).  It also services the ZumoDrive website.

Ok, so the data you store on the device is already being encrypted.  Cool.  But what if you want it to be really, really encrypted?  Should you be this paranoid?  Consider the excerpts from this article:

"As set forth in our privacy policy, and in compliance with United States law, Dropbox cooperates with United States law enforcement when it receives valid legal process, which may require Dropbox to provide the contents of your private Dropbox ... It is also worth noting that all companies that store user data (Google, Amazon, etc.) are not above the law and must comply with court orders and have similar statements in their respective terms of service."

I am only storing source code.  But it's not my source-code -- it's the IP of my company.  Therefore, your encryption methods do not satisfy my requirements and I shall have to devise an alternative strategy.

It's called Truecrypt.

I've already extensively blogged about Truecrypt in a 3-part post so I'm not going to cover the basics here.  Go read or review the series if you need a refresher on using Truecrypt and creating secure files and volumes.

Start TrueCrypt and create an encrypted file on your Zumo device.  I'm going to create a 500Mb encrypted file container on the Zumo drive.  I'm going to use multi-pass encryption scheme with a strong hash algorithm.  I'm going to use my 1Password program to randomly generate a password to control access to this container.  I'm creating this as a FAT filesystem, fully formatted.  Total time to format was about 10 seconds.

Once I've created the file container, I have to mount it.  I do this by selecting the file from within the Zumo filesystem share, using the TrueCrypt manager/program, and clicking "Mount".  I supply my password and the encrypted file container is now mounted to my desktop.  I now have two devices mounted -- the original Zumo drive and the TrueCrypt file container within the Zumo drive.

Were someone to access my Zumo device, without the TrueCrypt module, all they will see is a 500Mb file with my container name.  Stored inside the container is what appears to be random bits.  Perfect.

I can still store files to the Zumo device, along side my container file -- they will not be encrypted using TrueCrypt however.

The next step is to install my source code repository.  I use the best PHP IDE in the whole multi-verse:  PHPStorm by JetBrains.  It's so good, that this checkout process will be amazingly simple and fast.  My code repository will be checked-out from, and completely maintained in, subversion by the IDE.  Sweet.

I realize you may not yet be enlightened yet to PHPStorm and that's ok.  Use your inferior product to valiantly struggle to get the source code out from repository into the TrueCrypt volume.  You may even be successful!

For the rest of us, we simply select: Checkout From Version Control -> Subversion, and select the repository (svn+ssh://...).  The tricky part, for us Mac users, is that we have to locate the filesytem destination for the source-code files under the directory Volumes beneath the root mount-point.  In the Volumes directory, you will see (at least) two Volumes -- one for your Zumo drive and one for your encrypted container within the Zumo Drive.

If you want your source code to be stored in the encrypted container, within the Zumo drive, you have to select the encrypted container.  In the screenie shown, my container is creatively named "NO NAME".  This is the device I will select to check-out my source code into.  I'll create additional paths within the container that are proprietary to the application.

Once that's done, I click "OK" and, in the next dialog, tell PHPStorm to check-out from the HEAD and include external locations.  The final dialog asks me for version compatibility and I select 1.6.  The check-out process within PHPStorm takes off.

For my code base, checkout the entire code library and storing it to the encrypted volume took less than four minutes for slightly more than 100Mb worth of files.  True, there is processing overhead in retrieving the encrypted file form storage and de-crypting the file on-the-fly (and the same holds true in reverse) but the files are secure and my company's IP is protected.

From this point, as long as I have both the Zumo drive, and the TrueCrypt, software installed on whatever platform, I can access my source code, securely, from the cloud while ensuring that the source code itself remains current.

With the exception of the JetBrains PHPStorm IDE, the Zumo drive and the TrueCrypt software programs are open-source and free to use.

As a final caveat, this system puts you at the mercy of your ISP -- if there's no internet access, then you'll be unable to access your files.  Also, you'll want to make sure that you stage your source code regularly.  My general rule-of-thumb is to commit only when I reach the point where I don't want to have to re-engineer and re-type in the new code, or modifications, that I would lose should something happen to my cloud repository.

Final Notes

Zumo drive maintains it's files locally on your machine so that you always have off-line access to your files.  Therefore, you're really not at the mercy of your ISP.  You are, however, at the mercy of your hard drive space and your connectivity upload speed.  It took me hours to upload my 500Mb encrypted file container to Zumo -- at 77K/sec, it was not only painful, but it also bogged down my network speeds so that other idle entertainments (WoW) were pretty much impossible.

The upload speed lag, which I blame both my ISP and Zumo (throttling) for, meant that earning "achievements" from Zumo wasn't instantaneous -- I had to wait for network processing to complete before I could earn my "belts".  Eventually I did get up to my 2Gb of free storage so it's all good.

HowTo: Use PhpMyAdmin to Remote Admin mySQL DBs via SSH Tunnel...

Tech article that explains how to connect to a remote MySQL server via the open-source application: phpMyAdmin using secure-shell and tunneling.  Article was originally written for a mac platform but the process applies to any other mature operating system such as Linux.