instiki/test/unit/wiki_file_test.rb
Jacques Distler 5d15e3f39d Security: Instiki 0.16.2
On Webs with file uploads enabled, uploaded files were stored
(in version 0.16.1 and earlier) in the public/ directory.

This was a security threat. A miscreant could upload a .html file.
When a user clicked on the link to the file, it was opened (unsanitized)
in the browser.

As of version 0.16.2, uploaded files are stored in the webs/
directory. Now, when the user clicks on the link, the file is sent
with the

    Content-Disposition: attachment

header set, which causes the file to be downloaded, rather than opened
in the browser. As always, files downloaded from the internets should be
treated with caution. At least, this way, they are not aoutomatically 
opened in the browser.

To move your existing uploaded files to the new location, do a

     rake upgrade_instiki
2009-01-26 00:21:30 -06:00

85 lines
3.1 KiB
Ruby

require File.dirname(__FILE__) + '/../test_helper'
require 'fileutils'
class WikiFileTest < Test::Unit::TestCase
include FileUtils
fixtures :webs, :pages, :revisions, :system, :wiki_references
def setup
@web = webs(:test_wiki)
mkdir_p("#{RAILS_ROOT}/webs/wiki1/files/")
rm_rf("#{RAILS_ROOT}/webs/wiki1/files/*")
WikiFile.delete_all
end
def test_basic_store_and_retrieve_ascii_file
@web.wiki_files.create(:file_name => 'binary_file', :description => 'Binary file', :content => "\001\002\003")
binary = WikiFile.find_by_file_name('binary_file')
assert_equal "\001\002\003", binary.content
end
def test_basic_store_and_retrieve_binary_file
@web.wiki_files.create(:file_name => 'text_file', :description => 'Text file', :content => "abc")
text = WikiFile.find_by_file_name('text_file')
assert_equal "abc", text.content
end
def test_storing_an_image
rails_gif = File.open("#{RAILS_ROOT}/test/fixtures/rails.gif", 'rb') { |f| f.read }
assert_equal rails_gif.size, File.size("#{RAILS_ROOT}/test/fixtures/rails.gif")
@web.wiki_files.create(:file_name => 'rails.gif', :description => 'Rails logo', :content => rails_gif)
rails_gif_from_db = WikiFile.find_by_file_name('rails.gif')
assert_equal rails_gif.size, rails_gif_from_db.content.size
assert_equal rails_gif, rails_gif_from_db.content
end
def test_mandatory_fields_validations
assert_validation(:file_name, '', :fail)
assert_validation(:file_name, nil, :fail)
assert_validation(:content, '', :fail)
assert_validation(:content, nil, :fail)
end
def test_upload_size_validation
assert_validation(:content, 'a' * 100.kilobytes, :pass)
assert_validation(:content, 'a' * (100.kilobytes + 1), :fail)
end
def test_file_name_size_validation
assert_validation(:file_name, '', :fail)
assert_validation(:file_name, 'a', :pass)
assert_validation(:file_name, 'a' * 50, :pass)
assert_validation(:file_name, 'a' * 51, :fail)
end
def test_file_name_pattern_validation
assert_validation(:file_name, ".. Accep-table File.name", :pass)
assert_validation(:file_name, "/bad", :fail)
assert_validation(:file_name, "~bad", :fail)
assert_validation(:file_name, "..\bad", :fail)
assert_validation(:file_name, "\001bad", :fail)
assert_validation(:file_name, ".", :fail)
assert_validation(:file_name, "..", :fail)
end
def test_find_by_file_name
assert_equal @file1, WikiFile.find_by_file_name('file1.txt')
assert_nil WikiFile.find_by_file_name('unknown_file')
end
def assert_validation(field, value, expected_result)
values = {:file_name => '0', :description => '0', :content => '0'}
raise "WikiFile has no attribute named #{field.inspect}" unless values.has_key?(field)
values[field] = value
new_object = @web.wiki_files.create(values)
if expected_result == :pass then assert(new_object.valid?, new_object.errors.inspect)
elsif expected_result == :fail then assert(!new_object.valid?)
else raise "Unknown value of expected_result: #{expected_result.inspect}"
end
end
end