RailsSpace blog code security flaw
Posted over 2 years ago by Michael Hartl
I’d like to thank Fulvio Cusumano for pointing out a significant security problem in the RailsSpace blog code. He writes:
I’ve created an account on http://www.railsspace.com/ and my Username is “fulvio”. I am User ID 589. The following will not work, because I am not user 2. This is correct functionality because it tells me that it isn’t my blog. http://www.railsspace.com/blogs/2/posts/1;edit The actual security flaw I’ve found is that I don’t have a Post of ID #1 however if I access the following URL I can edit/update that post when I shouldn’t be able too! http://www.railsspace.com/blogs/589/posts/1;edit (589 is obviously me, but I don’t have a post of 1, however it DOES exist within your railsspace database).
This has now been fixed on the site, and in the RailsSpace zip files. The errata and code listings have also been updated to reflect the fix.
Here are the changes to make. First update the Posts fixture so that blog_id of the second post doesn’t match the blog of the test user:
test/fixtures/posts.yml
one: id: 1 blog_id: 1 title: MyString body: MyText created_at: 2007-01-16 15:34:32 updated_at: 2007-01-16 15:34:32 two: id: 2 blog_id: 2 title: MyString body: MyText created_at: 2007-01-16 15:34:32 updated_at: 2007-01-16 15:34:32
Then test the behavior we want:
test/functional/posts_controller_test.rb
class PostsControllerTest < Test::Unit::TestCase
fixtures :posts, :blogs, :users
.
.
.
def test_post_blog_mismatch
wrong_post = posts(:two) # Post exists, but belongs to wrong blog.
get :edit, :id => wrong_post, :blog_id => @post.blog
assert_response :redirect
assert_redirected_to hub_url
assert_equal "That isn't your blog post!", flash[:notice]
end
end
Finally, get the test to pass by putting in a new before_filter to make sure that post.blog and @blog agree:
app/controllers/posts_controller.rb
class PostsController < ApplicationController
helper :profile, :avatar
before_filter :protect, :protect_blog
before_filter :protect_post, :only => [:show, :edit, :update, :destroy]
.
.
.
private
# Ensure that user is blog owner, and create @blog.
def protect_blog
@blog = Blog.find(params[:blog_id])
user = User.find(session[:user_id])
unless @blog.user == user
flash[:notice] = "That isn't your blog!"
redirect_to hub_url
return false
end
end
def protect_post
post = Post.find(params[:id])
unless post.blog == @blog
flash[:notice] = "That isn't your blog post!"
redirect_to hub_url
return false
end
end
end
Comments
There are 0 comments on this post.