@@ -6,20 +6,23 @@ feature 'broken_auth' do
|
|||||||
@normal_user = UserFixture.normal_user
|
@normal_user = UserFixture.normal_user
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'TMI during login', :js => true do
|
scenario 'TMI during login - username' do
|
||||||
visit '/'
|
visit '/'
|
||||||
within('.signup') do
|
within('.signup') do
|
||||||
fill_in 'email', :with => @normal_user.email + 'not'
|
fill_in 'email', :with => @normal_user.email + 'not'
|
||||||
fill_in 'password', :with => @normal_user.clear_password
|
fill_in 'password', :with => @normal_user.clear_password
|
||||||
end
|
end
|
||||||
click_on 'Login'
|
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
|
within('.signup') do
|
||||||
fill_in 'email', :with => @normal_user.email
|
fill_in 'email', :with => @normal_user.email
|
||||||
fill_in 'password', :with => @normal_user.clear_password + 'not'
|
fill_in 'password', :with => @normal_user.clear_password + 'not'
|
||||||
end
|
end
|
||||||
click_on 'Login'
|
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
|
||||||
end
|
end
|
||||||
@@ -8,7 +8,7 @@ feature 'command injection' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
scenario 'injection attack on file upload', :js => true do
|
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')
|
legit_file = File.join(Rails.root, 'public', 'data', 'legit.txt')
|
||||||
File.open(legit_file, 'w') { |f| f.puts 'totes legit' }
|
File.open(legit_file, 'w') { |f| f.puts 'totes legit' }
|
||||||
@@ -21,10 +21,8 @@ feature 'command injection' do
|
|||||||
attach_file 'benefits_upload', hackety_file
|
attach_file 'benefits_upload', hackety_file
|
||||||
find(:xpath, "//input[@id='benefits_backup']", :visible => false).set 'true'
|
find(:xpath, "//input[@id='benefits_backup']", :visible => false).set 'true'
|
||||||
end
|
end
|
||||||
save_screenshot('screenshot.before.upload.png')
|
|
||||||
click_on 'Start Upload'
|
click_on 'Start Upload'
|
||||||
end
|
end
|
||||||
save_screenshot('screenshot.after.upload.png')
|
pending(:if => verifying_fixed?) { File.exists?(legit_file).should be_false }
|
||||||
File.exists?(legit_file).should be_false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -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[event_name]" value="Bad Guy" />
|
||||||
|
<input type="hidden" name="schedule[event_type]" value="pto" />
|
||||||
|
<input type="hidden" name="schedule[event_desc]" value="Fun Fun" />
|
||||||
|
<input type="hidden" name="date_range1" value="06/08/2013 - 06/09/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
|
||||||
@@ -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
|
||||||
@@ -13,9 +13,11 @@ feature 'insecure direct object reference' do
|
|||||||
download_url = first('.widget-body a')[:href]
|
download_url = first('.widget-body a')[:href]
|
||||||
visit download_url.sub(/name=(.*?)&/, 'name=../../config/database.yml&')
|
visit download_url.sub(/name=(.*?)&/, 'name=../../config/database.yml&')
|
||||||
|
|
||||||
page.status_code.should == 200
|
pending(:if => verifying_fixed?) {
|
||||||
page.response_headers['Content-Disposition'].should include('database.yml')
|
page.status_code.should == 200
|
||||||
page.response_headers['Content-Length'].should == '576'
|
page.response_headers['Content-Disposition'].should include('database.yml')
|
||||||
|
page.response_headers['Content-Length'].should == '576'
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'view any user work_info' do
|
scenario 'view any user work_info' do
|
||||||
@@ -24,6 +26,6 @@ feature 'insecure direct object reference' do
|
|||||||
@normal_user.user_id.should_not == 2
|
@normal_user.user_id.should_not == 2
|
||||||
visit '/users/2/work_info'
|
visit '/users/2/work_info'
|
||||||
|
|
||||||
first('td').text.should == 'Jack Mannino'
|
pending(:if => verifying_fixed?) { first('td').text.should == 'Jack Mannino' }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -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
|
||||||
@@ -23,8 +23,10 @@ feature 'sql injection' do
|
|||||||
end
|
end
|
||||||
click_on 'Submit'
|
click_on 'Submit'
|
||||||
|
|
||||||
@admin_user = User.where("admin='t'").first
|
pending(:if => verifying_fixed?) {
|
||||||
@admin_user.email.should == 'joe.admin@schmoe.com'
|
@admin_user = User.where("admin='t'").first
|
||||||
@admin_user.admin.should == true
|
@admin_user.email.should == 'joe.admin@schmoe.com'
|
||||||
|
@admin_user.admin.should == true
|
||||||
|
}
|
||||||
end
|
end
|
||||||
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
|
||||||
@@ -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
|
||||||
@@ -18,11 +18,10 @@ feature 'xss' do
|
|||||||
fill_in 'user_password_confirmation', :with => @normal_user.clear_password
|
fill_in 'user_password_confirmation', :with => @normal_user.clear_password
|
||||||
end
|
end
|
||||||
click_on 'Submit'
|
click_on 'Submit'
|
||||||
save_screenshot('screenshot.post.submit.png')
|
|
||||||
|
|
||||||
visit '/'
|
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
|
# might be nice to demonstrate posting cookie contents or somesuch, but
|
||||||
# this at least shows the vulnerability still exists.
|
# this at least shows the vulnerability still exists.
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
require 'spec_helper'
|
|
||||||
@@ -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
|
|
||||||
@@ -1,6 +1,15 @@
|
|||||||
require 'spec_helper.rb'
|
require 'spec_helper.rb'
|
||||||
|
|
||||||
describe User do
|
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
|
it "can be instantiated" do
|
||||||
User.new.should be_an_instance_of(User)
|
User.new.should be_an_instance_of(User)
|
||||||
end
|
end
|
||||||
@@ -10,7 +19,7 @@ describe User do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should require valid email" do
|
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
|
end
|
||||||
|
|
||||||
it "should require unique email" do
|
it "should require unique email" do
|
||||||
|
|||||||
@@ -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)
|
def login(user)
|
||||||
visit '/'
|
visit '/'
|
||||||
within('.signup') do
|
within('.signup') do
|
||||||
|
|||||||
Reference in New Issue
Block a user