Before_filter strange behaviour on update and create

Hi,

I wrote a authentication script and I’m calling it like this in every
class:

class Blah < ApplicationController

before_filter :auth

def auth
req_perm = Permission.find_by_name(“Permission Blah”)
access = AccessController.new()
if access.is_logged_in(session.session_id)
if
!access.get_current_user(session.session_id).role.permissions.include?
req_perm
redirect_to no_permission_url
end
else
redirect_to login_url
end
end

It works for the view pages but if an update or create is made then it
always redirects to the login_url. Acting like the user is not logged
in. But that’s wrong.

Did I miss something about the before_filer ? Does it work different on
update/create ?

On Mar 1, 2008, at 23:13 , Martin Sz wrote:

Did I miss something about the before_filer ? Does it work different
on
update/create ?

No.

No.

But why is it acting different ? It always redirects to the login_url
after update/create.

I guess at some point it can’t get the session.session_id. Might that be
the problem ?

In my scaffolded update/create methods it redirects to the show page
after update. The update/create work btw. The data get saved. But
afterwards you see the login instead of the show page.

Martin Sz wrote:

No.

But why is it acting different ? It always redirects to the login_url
after update/create.

I guess at some point it can’t get the session.session_id. Might that be
the problem ?

In my scaffolded update/create methods it redirects to the show page
after update. The update/create work btw. The data get saved. But
afterwards you see the login instead of the show page.

Ok, I can see the problem now. The session.session_id is different
directly after the update/create when it redirects to the show page.
Question is: why ?

I guess I’m using the wrong session_id. I thought “session.session_id”
is something like the server generates and that’s always the same ?

After login I have this session_id:

BAh7BzoMY3NyZl9pZCIlOTBjM2E5NjQxMTZjNTQwMDhkMjhmODhjY2RmYjQw%0AMjQiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7AAY6CkB1c2VkewA%3D–da80e3c07efbf5b09fef7418c5d404ca5f053812

After update/create I have this one:

BAh7BzoMY3NyZl9pZCIlZjg1NTBmOThmNmM2NGExNjU2NmQyMGEzMmQ2ZDNi%0AN2QiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7AAY6CkB1c2VkewA%3D–e6e7f072c7283b4de8773ed7c8e518b1eb2f5948

The first part is the same, but the end is different:

da80e3c07efbf5b09fef7418c5d404ca5f053812
e6e7f072c7283b4de8773ed7c8e518b1eb2f5948

On Mar 2, 2008, at 10:15 , Martin Sz wrote:

The first part is the same, but the end is different:

da80e3c07efbf5b09fef7418c5d404ca5f053812
e6e7f072c7283b4de8773ed7c8e518b1eb2f5948

When you store the session in the server the cookie stores a
session_id that is used as a key to retrieve the data on each request.

With cookie-based sessions session_id is not meaningful.

From your code looks like you are storing information in the server
based on the session_id. If I am correct that’s a bad practice. You’d
just store the information in the session itself, that’s its purpose:

session[:user_id] = user.id

and off the top of my head so that you see the idea:

before_filter :authenticate
def authenticate
  current_user = nil
  if session[:user_id]
    current_user = User.find(session[:user_id]) rescue nil
  end
  redirect_to login_path unless current_user
end

It goes without saying that implementing authentication yourself is
hard to justify normally, it is normally better to pick some plugin.

– fxn

Ok, so if I store something in the session like you described it then a
hacker wouldn’t be able to change it by simply editing a cookie ?

I mean the cookie wouldn’t include plain information like:

“user_id = 123”

I don’t really want to use a plugin. I would actually like to understand
as much as possible of what my application does :wink:

Another question: would it be best practice to store sessions in the
database instead of cookies which seems to be default ?

On Mar 2, 2008, at 11:00 , Martin Sz wrote:

Ok, so if I store something in the session like you described it
then a
hacker wouldn’t be able to change it by simply editing a cookie ?

I mean the cookie wouldn’t include plain information like:

“user_id = 123”

That’s the purpose of the right hand side of the cookie value, then
one you saw changed. That’s a digest of the data of the left hand side
computed by Rails. If the user tries to edit the data (which goes in
clear only encoded in Base64) Rails raises
CGI::Session::CookieStore::TamperedWithCookie and the request flow is
interrumped right away.

I don’t really want to use a plugin. I would actually like to
understand
as much as possible of what my application does :wink:

That’s good for learning, and normally bad for getting work done. When
you get confident with how things works you delegate as much as
possible. It is often the case that the author knows the problem to
solve better than you (“you” being generic) and has a good design and
good handling of corner cases or gotchas.

I changed the Session Store to ActiveRecord and if a user logs in
successfully then I store his or her UserID in session[:user_id]. To
check if he is logged in I just do if session[:user_id] as you said.

That works pretty good now.

Is this halfway secure now ?

On Mar 2, 2008, at 11:06 , Martin Sz wrote:

Another question: would it be best practice to store sessions in the
database instead of cookies which seems to be default ?

Not necessarily, cookie-based sessions are a valid storage. It is
valid to use the database as well of course.

Oh by the way I may already say thanks for your help xavier.

It can be so easy to do things with RoR…you just need to know how haha

Xavier N. wrote:

On Mar 2, 2008, at 11:06 , Martin Sz wrote:

Another question: would it be best practice to store sessions in the
database instead of cookies which seems to be default ?

Not necessarily, cookie-based sessions are a valid storage. It is
valid to use the database as well of course.

In the environment.rb I read:

Use the database for sessions instead of the cookie-based default,

which shouldn’t be used to store highly confidential information

(create the session table with ‘rake db:sessions:create’)

I mean if I stored login information then they are highly confidential I
guess.

No it’s not, as long as you only store the user_id and not the user
object itself. There is also a plugin out there that can make the
cookiebased session more secure by encrypting the data instead just
base64’ing it.

Hi Peter,

well with my current implementation it all depends on that user_id in
the session. If you manipulate this is then you are another user. For my
understanding: what would a hacker have to do to change the user_id of
the session ? He would need to access my database - right ? Because the
session’s are stored there now …

That would be pretty save … I mean if someone has access to your
database then you have lost anyways haha …

On 02 Mar 2008, at 12:19, Martin Sz wrote:

(create the session table with ‘rake db:sessions:create’)

I mean if I stored login information then they are highly
confidential I
guess.

No it’s not, as long as you only store the user_id and not the user
object itself. There is also a plugin out there that can make the
cookiebased session more secure by encrypting the data instead just
base64’ing it.

Best regards

Peter De Berdt

How can I edit my posts in this forum ? Let me guess: I can’t ?