How to move a wordpress multisite to a new “folder”

Moving a wordpress multisite (a SINGLE site, not an entire install) to a new subfolder (not really a folder as it’s virtual, but whatever) is not hard, but it’s also not as easy as it should be. Here are the steps I took:

  1. Change the site path from the Network Admin backend, and be sure to have it update “siteurl” and “home”. Make a note of the siteid while you’re here, which you can deduce from the “id=” parameter in the URL.
  2. Regenerate the permalinks from the “Settings -> Permalinks” menu – I just temporarily switch the permalink structure to something else and right back again to the original settings – there’s probably a more elegant way. If you’re using a custom structure, be sure to note it before you change as it won’t be retained in the text field.
  3. Fix all the links inside the content – I just used a mysql “update”, like this:
    update wp_<your multisite blog id>_posts set post_content = replace(post_content,’/oldpath/’,’/newpath/’);
    For bonus points, you can create a backup as a temporary table before the replace. Be aware this backup table will go away after you terminate your mysql connection.
    create temporary table wp_<your multisite blog id>_posts_tmp select * from wp_<your multisite blog id>_posts;
    This should fix all embedded media and page links – but you’ll still need to test, obviously.
  4. Clear your object / apc caches by restarting apache and doing whatever else you need to clear your object cache backend. Since we’re directly editing mysql tables, the object cache doesn’t get the clues it needs to decache stale values and you can get weird issues. If you’ve got a frontend page cache, clear that too.

These steps have worked fine here, but it’s a bit more manual than I had hoped.

Inferring password storage security through maximum password length requirements.

I’d like to follow up on a fairly obvious thought I tweeted today:

If a site has password length limits, it’s probably stored in plaintext. Hashed passwords (of any size) have a predicable length.

Excuse the typo, please. Explanation:

The sane operating procedure for password storage is to use a hash function (md5, sha256, bcrypt and similar) along with a “salt” to one-way hash the password. This hash is a known length, no matter how long the password is. For a hexidecimal md5 sum, it’s 32 characters.  When a user comes back to authenticate, you take the password they supply and the salt, calculate the hash, and match it against the hash you have on file. If the newly calculated sum matches the one you have on file, the user has entered their password properly.

There’s no logical reason to limit a hashed password’s length: a 4 character password and a 4000 character password will both calculate to the same size hash.

So if a website has a maximum password length, it means they are probably NOT hashing it and the limit they apply is to keep you from exceeding the column length of the table they store it in.  @abackstrom pointed out here that it’s probably the same situation for disallowed “special characters” – they shouldn’t care what you enter if all they are doing is hashing your password. If they do, they are probably storing it directly in a database.

Why is this bad? Many obvious reasons:

  • Your unencrypted password is sitting in a database, waiting to be stolen if/when the site in question is compromised,
  • Many people share passwords amongst websites, so a list of email addresses and unencrypted passwords can lead to many more compromised accounts on sites all over the web,
  • It’s unnecessary. There’s almost no valid reason to store an unhashed password, especially with all the excellent authentication frameworks out there.

What can you do?

If you’re a website user, complain! If a website has a maximum password length or a restriction against special characters: contact them! Tell them you don’t appreciate their lax security.  Ask them to support openID, ask them if they store passwords unhashed, just let them know this is important.

If you’re a developer, use an authentication library known to do things right in your language of choice. Don’t write your own, busted, authentication system.