2

So lets say I have a form for submitting a new post.

The form has a hidden field which specify's the category_id. We are also on the show view for that very category.

What I'm worried about, is that someone using something like firebug, might just edit the category id in the code, and then submit the form - creating a post for a different category.

Obviously my form is more complicated and a different scenario - but the idea is the same. I also cannot define the category in the post's create controller, as the category will be different on each show view...

Any solutions?

EDIT:

Here is a better question - is it possible to grab the Category id in the create controller for the post, if its not in a hidden field?

1
  • Recommended below, nest your Post resource under your Category and then rely on the route to load the appropriate category_id (URL). Then use a before_filter to validate access to the category Commented Sep 24, 2011 at 2:17

3 Answers 3

2

Does your site have the concept of permissions / access control lists on the categories themselves? If the user would have access to the other category, then I'd say there's no worry here since there's nothing stopping them from going to that other category and doing the same.

If your categories are restricted in some manner, then I'd suggest nesting your Post under a category (nested resource routes) and do a before_filter to ensure you're granted access to the appropriate category.

config/routes.rb

resources :categories do 
  resources :posts
end

app/controllers/posts_controller

before_filter :ensure_category_access

def create
  @post = @category.posts.new(params[:post])
  ...
end

private
def ensure_category_access
   @category = Category.find(params[:category_id])
   # do whatever you need to do. if you don't have to validate access, then I'm not sure I'd worry about this.  
   # If the user wants to change their category in their post instead of 
   # going to the other category and posting there, I don't think I see a concern?
end

URL would look like

GET /categories/1/posts/new POST /categories/1/posts

Sign up to request clarification or add additional context in comments.

3 Comments

If you have the before_filter on all actions (ie. no :except, :only options), then it's not required as the before_filter will load it.
ahh thanks! 1 last thing - my form before was form_for @post, but now its looking for a different route. How should I specify that?
form_for @post, :url => [@category, @post] (or if you prefer [@post.category, @post]) should work (no console sry) If you're going to nest Post under many resources, you can look at some of the nested resource gems out there for easier controller/route helpers. In short, you need to tell Rails what resource your @post is nested under.
2

pst is right- never trust the user. Double-check the value sent via the view in your controller and, if it does't match something valid, kick the user out (auto-logout) and send the admin an email. You may also want to lock the user's account if it keeps happening.

2 Comments

Wow! Your code must always bug free, otherwise, a bunch of users would get locked out all the time. :)
:) 2 locked out in the last 3 years or so.
2

Never, ever trust the user, of course ;-)

Now, that being said, it is possible to with a very high degree of confidence rely on hidden fields for temporal storage/staging (although this can generally also be handled entirely on the server with the session as well): ASP.NET follows this model and it has proven to be very secure against tampering if used correctly -- so what's the secret?

Hash validation aka MAC (Message Authentication Code). The ASP.NET MAC and usage is discussed briefly this article. In short the MAC is a hash of the form data (built using a server -- and perhaps session -- secret key) which is embedded in the form as a hidden field. When the form submission occurs this MAC is re-calculated from the data and then compared with the original MAC. Because the secrets are known only to the server it is not (realistically) possible for a client to generate a valid MAC from the data itself.

However, I do not use RoR or know what modules, if any, may implement security like this. I do hope that someone can provide more insight (in their own answer ;-) if such solutions exist, because it is a very powerful construct and easily allows safe per-form data association and validation.

Happy coding.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.