Security and incrementing integer ids

We’re close to launching our application to the public. Although this
will be a closed alpha I’m still kind of concerned about the security
of using an incrementing integer for the id to sensitive database
records.
I understand that these integer fields are ‘the rails way’ but I’m
thinking about having all the sensitive ids replaced with UUIDs
(GUIDs) but I’m not sure if this is really necessary. I’d rather not
do this right before launch since we have a thousand other things to
do that will be much more impressive, but securing users data is a
very high priority for me.
We are already pretty careful and rather than do something like this


@blog = Blog.find(params[:id])

we do


@blog = Blog.find(:first, :conditions => [‘id = ? and user_id = ?’,
params:[blog][:id], session[:user_id]])

but is it enough?
Does anyone have some opinion about this?

Dale

We are already pretty careful and rather than do something like this

but is it enough?
Does anyone have some opinion about this?

Well, I agree that simple numeric ID’s are easier to guess than a GUID,
but GUID’s are easy to guess too as long as you try enough combinations
:slight_smile:

My point being, that GUID’s only obscure the problem, don’t actually
solve
it. Solving it means that even if I know the ID’s associated with
your
user, I still can’t get to the data… and I’d say doing that through
your
second example is probably the right approach…

-philip

Hello Dale,

We’re close to launching our application to the public. Although this
will be a closed alpha I’m still kind of concerned about the security
of using an incrementing integer for the id to sensitive database
records.

[snip]

@blog = Blog.find(:first, :conditions => [‘id = ? and user_id = ?’,
params:[blog][:id], session[:user_id]])

How do you handle user authentication and login? If you were to use
the restful_auth plugin for example, which assigns a current_user to
every controller (or current_whateveryoucalledyourusermodel), then
you can use associations in your User model like so:

class User < ActiveRecord::Base
has_many :blogs
# lots more stuff here from the restful_auth plugin if you used it
end

Then you can do in your controllers:

@blog = current_user.blogs.find(:first)

…and so on, in every place you access user specific data. You can
wrap most of this in a before_filter so that user related data are
loaded at the start of each controller method, or when needed.

Even if you don’t use the restful_auth plugin, you can add a line
like this to your application.rb

before_filter {|cntrlr| cntrlr.user = User.find(session[:user_id]) }

The above line assigns the current authenticate user object to all
controllers before any actions are called. That way in your
controller you have always available the @user with the current
authenticated user and you can do:

@blog = @user.blogs.find(:first)

If someone tried to do a http://localhost/blogs/show/1 your show
action with the above line would not find the record if it does not
belong to the user.

but is it enough? Does anyone have some opinion about this?

I’d say your own method is sufficient, but not quite ‘The Rails Way’.
Use associations, and plugins like above to make your code easier to
read and maintain.

-christos

but is it enough?
Does anyone have some opinion about this?

Since you asked for an opinion… :slight_smile:

The second approach is a step closer to secure when you add the user_id
restriction and that the user id is part of the session (you’re not
passing
it via the parameter). Since you have some data that is viewed by
authenticated users, then maybe the controller action should be
protected
from the public.

It all depends on your application structure. If you have a use case
for
finding Blogs that are public and some that are private, then I would
have
two controllers a public one and a private one. For the private one,
restrict access to the controller/action as well.

I’ve seen a few posts using the security approach of “allow all unless
restricted”. I prefer the approach of “restrict all unless allowed”.

If you’re interested, I can send you my lockdown plugin with some
instructions on how to use. I’ve never found the time to distribute it
properly. Just email me directly (so my filters can pick it out). If
you
are interested, I can get it to you this weekend. Since it evolved over
time, I’ve never taken the time to refactor it to a self contained
plugin.
There are a couple of classes in my /lib dir I’ll need to include.

It’s a lot easier to implement than I may have made it seem, but it’s
not
trivial. Security never is.

good luck,
andy

Andy,

Thanks, I will take a look at that if you don’t mind. I’m always
looking for ways to make things more secure.
You can just email it back to this address if that’s OK.

Dale

Christos,

Thanks for this idea, to be honest we didn’t know you could do that as
we’re all a little junior on rails - always more to learn :slight_smile:

Dale

On Feb 7, 4:49 pm, Christos Z. [email protected]