1

I'm trying to obfuscate all the ids that leave the server, i.e., ids appearing in URLs and in the HTML output.

I've written a simple Base62 lib that has the methods encode and decode. Defining—or better—overwriting the id method of an ActiveRecord to return the encoded version of the id and adjusting the controller to load the resource with the decoded params[:id] gives me the desired result. The ids now are base62 encoded in the urls and the response displays the correct resource.

Now I started to notice that subresources defined through has_many relationships aren't loading. e.g. I have a record called User that has_many Posts. Now User.find(1).posts is empty although there are posts with user_id = 1. My explanation is that ActiveRecord must be comparing the user_id of Post with the method id of User—which I've overwritten—instead of comparing with self[:id]. So basically this renders my approach useless.

What I would like to have is something like defining obfuscates_id in the model and that the rest would be taken care of, i.e., doing all the encoding/decoding at the appropriate locations and preventing ids to be returned by the server.

Is there any gem available or does somebody have a hint how to accomplish this? I bet I'm not the first trying this.

fphilipe
  • 9,739
  • 1
  • 40
  • 52
  • 1
    Wasting time in obfuscation is wasting time that could have been used to improve the overall security. Or is there another reason for obfuscating? – LukeN May 11 '10 at 22:25
  • 3
    ID Obfuscation isn't a security measurement IMHO. It only hides certain information contained in IDs such as how many registered users there are on a site or how many posts. Replacing them with simple base62 encoded versions doesn't reveal this kind of information. I'm not willing to lose too much time with that, that's why it would be cool if I could simply call `obfuscates_id` in the model. – fphilipe May 11 '10 at 22:35
  • It matters how many users or posts are on the site? – Earlz May 11 '10 at 22:36
  • 5
    It's just a piece of information that I'd prefer not to share, especially not with my competitors. Anyway, that's not the point of my question to be discussing if this makes sense or not. – fphilipe May 11 '10 at 22:40
  • 1
    You won't really be hiding the information with Base62... Maybe you could create random ids instead – jessecurry May 12 '10 at 01:49
  • Everyone who will want to know how many posts you have will be able to see that number. Everyone else wouldn't notice it even if it was just an integer value. – Tomas Markauskas May 12 '10 at 01:57
  • @jessecurry: I think if I encode it using the 62 characters in a random order like 0d2jfXH8sQNnryoGS instead of sequential like [0-9][a-z][A-Z] it would be pretty hard or near impossible to figure out the order. You would have to create 62 sequential new records. – fphilipe May 12 '10 at 05:19
  • 62 random characters isn't really Base62 encoding. In fact, any encoding that you use could be reversed, so the security gain is nil. BASE64: `VGhpcyB0ZXh0IGlzIG5vdCBzZWNyZXQu` – jessecurry May 12 '10 at 13:08

1 Answers1

3

What you are describing sounds like a specialized application of a URL slug. Take a look at plugins like acts_as_sluggable or friendly_id. Also look at overriding the to_param method on your User model.

Maybe start here: Best Permalinking for Rails

Community
  • 1
  • 1
jdl
  • 17,702
  • 4
  • 51
  • 54