forked from technoweenie/mephisto
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Security: Force all GET requests to be read-only
The W3C makes a clear distinction between GET and POST requests. GET requests should only cause "safe" actions, and the user should never be held accountable for making GET requests. See the following for an overview: http://www.w3.org/2001/tag/doc/whenToUseGet.html The Rails 'protect_against_forgery' function (and possibly some web browsers) rely on the distinction between GET and POST to provide protection against CSRF attacks. See: http://en.wikipedia.org/wiki/Cross-site_request_forgery http://guides.rubyonrails.org/security.html#_csrf_countermeasures Unfortunately, enforcing these rules in rather difficult, especially in a large application with lots of controllers and plugins. So this patch applies a rather heavy-handed fix: We globally block database writes during GET requests, and specifically override that policy in one or two places. All of our current overrides invoke User#reset_token!. I haven't performed a full security analysis of allowing User#reset_token! (or updates to session[:user] based on our "remember me" token) in a GET request. For now, I'm going to go ahead and allow this activity--if we actually have some sort of vulnerability here, it affects a wide range of web applications. Note that this patch may break some part of the /admin interface. I've tried posting articles and other basic stuff, but I haven't used the lesser-known corners of /admin since making these changes. Please report any problems.
- Loading branch information
Showing
6 changed files
with
102 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
module ActiveRecord | ||
class Base | ||
# Are ActiveRecord::Base objects currently readonly? | ||
def self.all_records_are_readonly? | ||
Thread.current[:all_records_are_readonly] | ||
end | ||
|
||
def readonly_with_global_flag? | ||
self.class.all_records_are_readonly? || readonly_without_global_flag? | ||
end | ||
alias_method_chain :readonly?, :global_flag | ||
|
||
# Make all ActiveRecord::Base objects readonly within a block. | ||
def self.with_readonly_records # :yield: | ||
saved = all_records_are_readonly? | ||
begin | ||
Thread.current[:all_records_are_readonly] = true | ||
yield | ||
ensure | ||
Thread.current[:all_records_are_readonly] = saved | ||
end | ||
end | ||
|
||
# Make all ActiveRecord::Base objects writable within a block. | ||
def self.with_writable_records # :yield: | ||
saved = all_records_are_readonly? | ||
begin | ||
Thread.current[:all_records_are_readonly] = false | ||
yield | ||
ensure | ||
Thread.current[:all_records_are_readonly] = saved | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
require File.dirname(__FILE__) + '/../spec_helper' | ||
|
||
# Verify that our readonly_record patches are working. | ||
describe "Any record" do | ||
before :each do | ||
@article = Article.make(:title => "Original title") | ||
end | ||
|
||
it "should be writable by default" do | ||
assert !ActiveRecord::Base.all_records_are_readonly? | ||
@article.title = "Hello!" | ||
@article.save! | ||
end | ||
|
||
it "should not be writable inside with_readonly_records" do | ||
assert_raise ActiveRecord::ReadOnlyRecord do | ||
ActiveRecord::Base.with_readonly_records do | ||
assert ActiveRecord::Base.all_records_are_readonly? | ||
@article.title = "Hello!" | ||
@article.save! | ||
end | ||
end | ||
end | ||
|
||
it "should be writable inside with_writable_records" do | ||
ActiveRecord::Base.with_readonly_records do | ||
ActiveRecord::Base.with_writable_records do | ||
assert !ActiveRecord::Base.all_records_are_readonly? | ||
@article.title = "Hello!" | ||
@article.save! | ||
end | ||
end | ||
end | ||
end | ||
|