Security: Enforce POSTs

Spammers can bypass form_spam_protect plugin by using GET instead of POST.

Fix this, by ensuring that unsafe operations are POSTs, rather than GETs.
This commit is contained in:
Jacques Distler 2007-10-07 17:59:20 +00:00
parent 4199843e08
commit ab7f429a10
4 changed files with 38 additions and 3 deletions

View file

@ -27,6 +27,11 @@ class AdminController < ApplicationController
def create_web
if params['address']
unless (request.post? || ENV["RAILS_ENV"] == "test")
headers['Allow'] = 'POST'
render(:status => 405, :text => 'You must use an HTTP POST')
return
end
# form submitted
if @wiki.authenticate(params['system_password'])
begin
@ -49,6 +54,11 @@ class AdminController < ApplicationController
def edit_web
system_password = params['system_password']
if system_password
unless (request.post? || ENV["RAILS_ENV"] == "test")
headers['Allow'] = 'POST'
render(:status => 405, :text => 'You must use an HTTP POST')
return
end
# form submitted
if wiki.authenticate(system_password)
begin
@ -81,6 +91,11 @@ class AdminController < ApplicationController
end
def remove_orphaned_pages
unless (request.post? || ENV["RAILS_ENV"] == "test")
headers['Allow'] = 'POST'
render(:status => 405, :text => 'You must use an HTTP POST')
return
end
if wiki.authenticate(params['system_password_orphaned'])
wiki.remove_orphaned_pages(@web_name)
flash[:info] = 'Orphaned pages removed'

View file

@ -1,6 +1,7 @@
# Controller responsible for serving files and pictures.
require 'zip/zip'
require 'sanitize'
class FileController < ApplicationController
@ -11,6 +12,11 @@ class FileController < ApplicationController
def file
@file_name = params['id']
if params['file']
unless (request.post? || ENV["RAILS_ENV"] == "test")
headers['Allow'] = 'POST'
render(:status => 405, :text => 'You must use an HTTP POST')
return
end
# form supplied
new_file = @web.wiki_files.create(params['file'])
if new_file.valid?
@ -61,7 +67,8 @@ class FileController < ApplicationController
if @web.allow_uploads?
return true
else
render :status => 403, :text => 'File uploads are blocked by the webmaster'
@hide_navigation = true
render(:status => 403, :text => 'File uploads are blocked by the webmaster', :layout => true)
return false
end
end
@ -77,6 +84,10 @@ class FileController < ApplicationController
page_content = entry.get_input_stream.read
logger.info "Processing page '#{page_name}'"
begin
if !page_content.is_utf8?
logger.info "Page '#{page_name}' contains non-utf8 character data. Skipping."
next
end
existing_page = @wiki.read_page(@web.address, page_name)
if existing_page
if existing_page.content == page_content

View file

@ -224,6 +224,11 @@ class WikiController < ApplicationController
def save
render(:status => 404, :text => 'Undefined page name') and return if @page_name.nil?
unless (request.post? || ENV["RAILS_ENV"] == "test")
headers['Allow'] = 'POST'
render(:status => 405, :text => 'You must use an HTTP POST')
return
end
author_name = params['author']
author_name = 'AnonymousCoward' if author_name =~ /^\s*$/

View file

@ -87,8 +87,12 @@ class FileControllerTest < Test::Unit::TestCase
# User uploads the picture
picture = File.read("#{RAILS_ROOT}/test/fixtures/rails.gif")
# updated from post to get - post fails the spam protection (no javascript)
r = get :file, :web => 'wiki1',
:file => {:file_name => 'rails-e2e.gif', :content => StringIO.new(picture)}
# Moron! If substituting GET for POST actually works, you
# have much, much bigger problems.
r = get :file, :web => 'wiki1',
:file => {:file_name => 'rails-e2e.gif',
:content => StringIO.new(picture),
:description => 'Rails, end-to-end'}
assert_redirected_to({})
assert @web.has_file?('rails-e2e.gif')
assert_equal(picture, WikiFile.find_by_file_name('rails-e2e.gif').content)