Deprecated Behaviour

The inane, sometimes insane, ramblings from the mind of Brenton Alker.

Trim() Validation

While writing a fairly standard sign-up/log-in system, I got to the point of validating the password to make sure it only contained acceptable characters. Now for me this would usually mean a regular expression. But, since this system wasn’t for me I decided to make the “valid characters” configurable, and generally the people configuring it won’t be able to write a regular expression.

My solution is to use php’s trim() (or more specifically rtrim(), but it doesn’t really matter) by passing the users input as the first argument, and the string of valid characters as the second; I should get an empty string in return. So the test, only allowing lowercase letters, becomes:

1
2
3
4
<?php
    if ('' !== rtrim($input, 'abcdefghijklmnopqrstuvwxyz')) {
    return false;
    }

Simple! I don’t know how it compares speed wise with other methods, but it seems simple and effective and I can’t imagine it’s terribly slow unless your strings get larger.

I’m also not sure how it would handle multi-byte characters. But I don’t think it would be a problem if it doesn’t. Anyone got any insight?

An Attempt at Restricted Auto-Login

The system I have been building is a direct marketing system (don’t hate me, it’s opt-in) and to be compliant with their ethics policy it requires “2 click unsubscribe” functionality from all its email campaigns; 1 click on the link in the email, and 1 click on a big “Don’t Ever Send Me Email Again” button. So people actually have an option to opt out at any time, as any good (and I use that word in the relative sense) email marketing system should.

The problem this poses for me though, is how can I let a member unsubscribe without authenticating themselves? Authentication would take more than 2 clicks! The obvious solution is to not require authentication by simply adding the members identifier (email address, user name, database id, whatever can identify them uniquely) to the link. So I would have a URL something like:

http://example.com/member/unsubscribe?member=1234

And simply make all the options on that page act on the member identified by the identifier. Great! Until a malicious netizen comes along, seeing the scheme decides to systematically unsubscribe all my members. This would be achieved easily by guessing the identifiers, made even easier because they’re sequential, and clicking the unsubscribe button.

The initial solution is to use some other “key” in the link, one that is not so easy to guess. So a key was added, giving the url a form like:

http://example.com/member/unsubscribe?member=1234&key=SECRETKEY

Were SECRETKEY is a key they is generated randomly when the user signs up and stored with their account details. Using this, the system would allow a user to log in simply by clicking the link, they could then unsubscribe.

The problem being, of course, that by simply logging the user into their account anyone who has the link has full access to the account without needing to know any more information. So they could then read (and change) email addresses, passwords etc. Not ideal.

My solution has been to take the key a step further, and limit it to only the intended page. In this case the unsubscribe page. So my new url looks like this:

http://example.com/member/unsubscribe?token=1234:HASH

I’ve removed the member variable and combined it into a delimited token. This was mainly because I thought it looked a little nicer, it would function just as well as a separate variable. The real change is in the HASH. The new hash still uses the SECRETKEY that was used in the previous iteration, except it is now combined with the url that I want to give them access to, and an added salt so all tokens can be invalidated if required. In PHP, this looks something like this:

<code>$allowedUrl = '/member/unsubscribe';
$hash = md5($salt . $allowedUrl . ':' . $secretKey);
$token = $id . ':' . $hash;
</code>

On the page, to allow access, the token is decomposed, the member’s identifier extracted, and their key retrieved. Their key is then used in the same process to generate a hash for the URL they are requesting. If the hashes match, they have access. To make it a little more user friendly, the allowed URL is added to their session, so they still have access to the page even if they lose the token from the URL. If they hit any other page with the restricted URL in their session they are logged out and sent back to re-authenticate.

One shortfall that I am aware of, and that was pointed out in a discussion on #phpc, is the members secret keys should ideally be rotated, so it can only be used once. This would mean that stealing a link would at worst allow one login, and only to one page. This may be implemented if it doesn’t impact too much on usability (that classic trade-off, security vs. convenience).

Now, I am not a security expert and as such don’t recommend anyone take my advice (is this good enough for a disclaimer), but apart from the one caveat mentioned, I think this solution meets the requirements without forfeiting too much in security. Any comments or advice on the technique are, as always, appreciated.

My Web 2.0 World

The last month or so I’ve been trying to actually get into the whole “Web 2.0” (I don’t like the term by the way) world. I know it’s old news, and it’s not like it’s new to me either. I just recently thought about all the web applications that seem to be so popular that I have dormant accounts on, the main ones are;

Facebook, well, that’s taken MySpace’s place as the social network I only passively interact with. The other three are of more interest to me, so I’ve decided to try and use them for something useful.

Flickr is a fairly easy one, I have a large collection of digitized photographs spanning a few years which are for the most part sorted/tagged thanks to F-Spot which has the ability to sync with many popular image hosting sites including Flickr and Google’s Picasaweb. So I am gradually building the on-line collection, I initially intended to just dump the lot on there (if only as a backup) but then realised that there are a few too many GB for that.

Del.icio.us I get, but as someone who has never been a big collector of bookmarks, I don’t find too useful. My bookmarks in my browser have always been a mess, mainly because they are all just temporary. Any site I visit on a regular basis for any extended period of time, I know the address for (or at least know a good google query to find it). But, in the spirit of my trying to “giving it a go” I installed the firefox extension and added my “recent bookmarks” to this page using the wordpress plugin (over there on the right somewhere). I must say I’m using it more, but still not a great deal.

Twitter is an oddity to me, it seems incredibly popular; in spite of it’s apparent unreliability. To me it seems to sit somewhere between a very slow IRC and a short message mailing list. I think the only advantage I can see is that it can work mobile, though I’ve not had much luck keeping that working for more than a day or two. Most other people who have complained about “Not Getting It” when it comes to Twitter seem to be told to install a desktop client, as it is much more conducive to regular use than the website. So, I diligently installed Spaz, an Adobe Air based client, which means I now get little popups telling me when someone “tweets”. That makes it more convenient, so far it hasn’t made it more interesting.

Although all the tools are very cool, maybe this “Social Web” thing just isn’t for me. Then again, maybe it’s this whole “Social” thing that just doesn’t work for me ;)