Merge branch 'master' of https://github.com/OWASP/railsgoat
This commit is contained in:
@@ -97,9 +97,6 @@ To run just one spec:
|
|||||||
$ rails training SPEC=spec/vulnerabilities/sql_injection_spec.rb
|
$ rails training SPEC=spec/vulnerabilities/sql_injection_spec.rb
|
||||||
```
|
```
|
||||||
|
|
||||||
NOTE: As vulnerabilities are fixed in the application, these specs will not change to `passing`, but to `pending`.
|
|
||||||
|
|
||||||
|
|
||||||
## MySQL Environment
|
## MySQL Environment
|
||||||
|
|
||||||
By default in development mode Railsgoat runs with a SQLite database. There is an environment defined to use MySQL. For some of the SQL injection vulnerabilities to work you have to run the app with MySQL as the database. The following steps will setup and run Railsgoat to use MySQL. *MySQL must be installed and running before running these steps*
|
By default in development mode Railsgoat runs with a SQLite database. There is an environment defined to use MySQL. For some of the SQL injection vulnerabilities to work you have to run the app with MySQL as the database. The following steps will setup and run Railsgoat to use MySQL. *MySQL must be installed and running before running these steps*
|
||||||
@@ -139,7 +136,7 @@ Alternatively, you can run MailCatcher in the foreground by running `mailcatcher
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
As changes are made to the application, the Capybara RSpecs can be used to verify that the vulnerabilities in the application are still intact. To use them in this way, and have them `pass` instead of `fail`, set the `RAILSGOAT_MAINTAINER` environment variable.
|
As changes are made to the application, the Capybara RSpecs can be used to verify that the vulnerabilities in the application are still intact. To use them in this way, and have them change to `pending` instead of `fail`, set the `RAILSGOAT_MAINTAINER` environment variable.
|
||||||
|
|
||||||
Conversion to the OWASP Top Ten 2013 completed in November, 2013.
|
Conversion to the OWASP Top Ten 2013 completed in November, 2013.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require "spec_helper.rb"
|
require "spec_helper.rb"
|
||||||
|
|
||||||
describe User do
|
describe Benefits do
|
||||||
before(:all) do
|
before(:all) do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
DatabaseCleaner.strategy = :transaction
|
DatabaseCleaner.strategy = :transaction
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ def verifying_fixed?
|
|||||||
|
|
||||||
**NOTE: The RSpec pending feature is used to toggle the outcome of these specs
|
**NOTE: The RSpec pending feature is used to toggle the outcome of these specs
|
||||||
between Training mode and RailsGoat Maintainer mode. When the vulnerabilities
|
between Training mode and RailsGoat Maintainer mode. When the vulnerabilities
|
||||||
are removed, the specs will not "pass," but rather go into a "pending" state.
|
are removed, the specs will pass instead. Try to get a fully passing suite.
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
|
|
||||||
NOTICE
|
NOTICE
|
||||||
|
|||||||
@@ -2,34 +2,39 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "broken_auth" do
|
feature "broken_auth" do
|
||||||
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
|
||||||
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "one\nTutorial: https://github.com/OWASP/railsgoat/wiki/A2-Credential-Enumeration" do
|
scenario "one\nTutorial: https://github.com/OWASP/railsgoat/wiki/A2-Credential-Enumeration" do
|
||||||
|
wrong_email = normal_user.email + "not"
|
||||||
|
|
||||||
visit "/"
|
visit "/"
|
||||||
within(".signup") do
|
within(".signup") do
|
||||||
fill_in "email", with: @normal_user.email + "not"
|
fill_in "email", with: wrong_email
|
||||||
fill_in "password", with: @normal_user.clear_password
|
fill_in "password", with: normal_user.clear_password
|
||||||
end
|
end
|
||||||
within(".actions") do
|
within(".actions") do
|
||||||
click_on "Login"
|
click_on "Login"
|
||||||
end
|
end
|
||||||
pending if verifying_fixed?
|
|
||||||
expect(find("div#flash_notice").text).to eq("#{@normal_user.email}not doesn't exist!")
|
expect(find("div#flash_notice").text).not_to include(wrong_email)
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "two\nTutorial: https://github.com/OWASP/railsgoat/wiki/A2-Credential-Enumeration" do
|
scenario "two\nTutorial: https://github.com/OWASP/railsgoat/wiki/A2-Credential-Enumeration" do
|
||||||
visit "/"
|
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
|
||||||
within(".actions") do
|
within(".actions") do
|
||||||
click_on "Login"
|
click_on "Login"
|
||||||
end
|
end
|
||||||
pending if verifying_fixed?
|
|
||||||
expect(find("div#flash_notice").text).to eq("Incorrect Password!")
|
expect(find("div#flash_notice").text).not_to include("Incorrect Password!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,18 +3,20 @@ require "spec_helper"
|
|||||||
require "tmpdir"
|
require "tmpdir"
|
||||||
|
|
||||||
feature "command injection" do
|
feature "command injection" do
|
||||||
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A1-Command-Injection", js: true do
|
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A1-Command-Injection", 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" }
|
||||||
|
|
||||||
visit "/users/#{@normal_user.id}/benefit_forms"
|
visit "/users/#{normal_user.id}/benefit_forms"
|
||||||
Dir.mktmpdir do |dir|
|
Dir.mktmpdir do |dir|
|
||||||
hackety_file = File.join(dir, "test; cd public && cd data && rm -f * ;")
|
hackety_file = File.join(dir, "test; cd public && cd data && rm -f * ;")
|
||||||
File.open(hackety_file, "w") { |f| f.print "mwahaha" }
|
File.open(hackety_file, "w") { |f| f.print "mwahaha" }
|
||||||
@@ -24,7 +26,7 @@ feature "command injection" do
|
|||||||
end
|
end
|
||||||
click_on "Start Upload"
|
click_on "Start Upload"
|
||||||
end
|
end
|
||||||
pending if verifying_fixed?
|
|
||||||
expect(File.exist?(legit_file)).to be_falsey
|
expect(File.exist?(legit_file)).to be_truthy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ require "spec_helper"
|
|||||||
require "tmpdir"
|
require "tmpdir"
|
||||||
|
|
||||||
feature "csrf" do
|
feature "csrf" do
|
||||||
before do
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/R5-A8-CSRF", js: true do
|
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/R5-A8-CSRF", js: true do
|
||||||
@@ -13,7 +15,7 @@ feature "csrf" do
|
|||||||
# TODO: is there a way to get this without visiting root first?
|
# TODO: is there a way to get this without visiting root first?
|
||||||
base_url = current_url
|
base_url = current_url
|
||||||
|
|
||||||
login @normal_user
|
login(normal_user)
|
||||||
|
|
||||||
Dir.mktmpdir do |dir|
|
Dir.mktmpdir do |dir|
|
||||||
hackety_file = File.join(dir, "form.on.bad.guy.site.html")
|
hackety_file = File.join(dir, "form.on.bad.guy.site.html")
|
||||||
@@ -40,7 +42,6 @@ feature "csrf" do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pending if verifying_fixed?
|
expect(normal_user.reload.paid_time_off.schedule.last.event_name).not_to eq("Bad Guy")
|
||||||
expect(@normal_user.reload.paid_time_off.schedule.last.event_name).to eq("Bad Guy")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,33 +2,31 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "insecure direct object reference" do
|
feature "insecure direct object reference" do
|
||||||
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
let(:another_user) { User.find_by(id: 2) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack one" do
|
scenario "attack one" do
|
||||||
login(@normal_user)
|
login(normal_user)
|
||||||
|
|
||||||
visit "/users/#{@normal_user.id}/benefit_forms"
|
visit "/users/#{normal_user.id}/benefit_forms"
|
||||||
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&")
|
||||||
|
|
||||||
pending if verifying_fixed?
|
expect(page.status_code).not_to eq(200)
|
||||||
|
expect(page.response_headers["Content-Disposition"]).not_to include("database.yml")
|
||||||
expect(page.status_code).to eq(200)
|
|
||||||
expect(page.response_headers["Content-Disposition"]).to include("database.yml")
|
|
||||||
expect(page.response_headers["Content-Length"]).to eq("710")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack two\nTutorial: https://github.com/OWASP/railsgoat/wiki/A4-Insecure-Direct-Object-Reference" do
|
scenario "attack two\nTutorial: https://github.com/OWASP/railsgoat/wiki/A4-Insecure-Direct-Object-Reference" do
|
||||||
login(@normal_user)
|
expect(normal_user.id).not_to eq(another_user.id)
|
||||||
expect(@normal_user.id).not_to eq(2)
|
|
||||||
another_user = User.find(2)
|
|
||||||
|
|
||||||
visit "/users/#{another_user.id}/work_info"
|
visit "/users/#{another_user.id}/work_info"
|
||||||
|
|
||||||
pending if verifying_fixed?
|
expect(first("td").text).not_to include(another_user.name)
|
||||||
expect(first("td").text).to eq(another_user.full_name)
|
expect(first("td").text).to include(normal_user.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,37 +2,37 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "mass assignment" do
|
feature "mass assignment" do
|
||||||
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack one" do
|
scenario "attack one" do
|
||||||
expect(@normal_user.admin).to be_falsey
|
expect(normal_user.admin).to be_falsey
|
||||||
|
login(normal_user)
|
||||||
|
|
||||||
login(@normal_user)
|
params = { user: { admin: "t",
|
||||||
|
id: normal_user.id,
|
||||||
|
password: normal_user.clear_password,
|
||||||
|
password_confirmation: normal_user.clear_password }}
|
||||||
|
|
||||||
params = { user: { admin: "t",
|
page.driver.put "/users/#{normal_user.id}.json", params
|
||||||
id: @normal_user.id,
|
|
||||||
password: @normal_user.clear_password,
|
|
||||||
password_confirmation: @normal_user.clear_password}}
|
|
||||||
page.driver.put "/users/#{@normal_user.id}.json", params
|
|
||||||
|
|
||||||
pending if verifying_fixed?
|
expect(normal_user.reload.admin).to be_falsy
|
||||||
expect(@normal_user.reload.admin).to be_truthy
|
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack two, Tutorial: https://github.com/OWASP/railsgoat/wiki/R5-Extras-Mass-Assignment-Admin-Role" do
|
scenario "attack two, Tutorial: https://github.com/OWASP/railsgoat/wiki/R5-Extras-Mass-Assignment-Admin-Role" do
|
||||||
params = {user: {admin: "t",
|
params = { user: { admin: "t",
|
||||||
email: "hackety@h4x0rs.c0m",
|
email: "hackety@h4x0rs.c0m",
|
||||||
first_name: "hackety",
|
first_name: "hackety",
|
||||||
last_name: "hax",
|
last_name: "hax",
|
||||||
password: "foobarewe",
|
password: "foobarewe",
|
||||||
password_confirmation: "foobarewe"}}
|
password_confirmation: "foobarewe" }}
|
||||||
|
|
||||||
page.driver.post "/users", params
|
page.driver.post "/users", params
|
||||||
|
|
||||||
pending if verifying_fixed?
|
expect(User.find_by(email: "hackety@h4x0rs.c0m")).to be_nil
|
||||||
expect(User.last.email).to eq("hackety@h4x0rs.c0m")
|
|
||||||
expect(User.last.admin).to be_truthy
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,22 +2,27 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "password complexity" do
|
feature "password complexity" do
|
||||||
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "one\nTutorial: https://github.com/OWASP/railsgoat/wiki/A2-Lack-of-Password-Complexity" do
|
scenario "one\nTutorial: https://github.com/OWASP/railsgoat/wiki/A2-Lack-of-Password-Complexity" do
|
||||||
|
new_user_email = normal_user.email + "two"
|
||||||
|
|
||||||
visit "/signup"
|
visit "/signup"
|
||||||
within(".signup") do
|
within(".signup") do
|
||||||
fill_in "user_email", with: @normal_user.email + "not"
|
fill_in "user_email", with: new_user_email
|
||||||
fill_in "user_first_name", with: @normal_user.first_name
|
fill_in "user_first_name", with: normal_user.first_name
|
||||||
fill_in "user_last_name", with: @normal_user.last_name + "not"
|
fill_in "user_last_name", with: normal_user.last_name + "not"
|
||||||
fill_in "user_password", with: "password"
|
fill_in "user_password", with: "password"
|
||||||
fill_in "user_password_confirmation", with: "password"
|
fill_in "user_password_confirmation", with: "password"
|
||||||
end
|
end
|
||||||
click_on "Submit"
|
click_on "Submit"
|
||||||
pending if verifying_fixed?
|
|
||||||
expect(current_path).to eq("/dashboard/home")
|
expect(User.find_by(email: new_user_email)).to be_nil
|
||||||
|
expect(current_path).to eq("/signup")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,18 +2,20 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "improper password hashing" do
|
feature "improper password hashing" do
|
||||||
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "with just md5\nTutorial: https://github.com/OWASP/railsgoat/wiki/A6-Sensitive-Data-Exposure-Insecure-Password-Storage" do
|
scenario "with just md5\nTutorial: https://github.com/OWASP/railsgoat/wiki/A6-Sensitive-Data-Exposure-Insecure-Password-Storage" do
|
||||||
new_pass = "testPassw0rd!"
|
new_pass = "testPassw0rd!"
|
||||||
@normal_user.password = new_pass
|
normal_user.password = new_pass
|
||||||
@normal_user.password_confirmation = new_pass
|
normal_user.password_confirmation = new_pass
|
||||||
@normal_user.save
|
normal_user.save!
|
||||||
pending if verifying_fixed?
|
|
||||||
expect(Digest::MD5.hexdigest(new_pass)).to eq(@normal_user.password)
|
expect(normal_user.password).not_to eq(Digest::MD5.hexdigest(new_pass))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,19 +2,23 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "sensitive data exposure" do
|
feature "sensitive data exposure" do
|
||||||
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
let(:user_ssn) { "999-99-9999" }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
normal_user.work_info.update_attribute(:SSN, user_ssn)
|
||||||
@normal_user.work_info.update_attribute(:SSN, "999-99-9999")
|
|
||||||
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
# this won't work with javascript_driver, as it'll apply the javascript
|
# this won't work with javascript_driver, as it'll apply the javascript
|
||||||
# function to mask this value and the source will be overwritten.
|
# function to mask this value and the source will be overwritten.
|
||||||
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A6-Sensitive-Data-Exposure-Cleartext-Storage-SSNs" do
|
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A6-Sensitive-Data-Exposure-Cleartext-Storage-SSNs" do
|
||||||
login @normal_user
|
login(normal_user)
|
||||||
|
|
||||||
visit "/users/#{@normal_user.id}/work_info"
|
visit "/users/#{normal_user.id}/work_info"
|
||||||
pending if verifying_fixed?
|
|
||||||
expect(page.source).to include "999-99-9999"
|
expect(page.source).not_to include(user_ssn)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,53 +2,31 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "sql injection" do
|
feature "sql injection" do
|
||||||
before(:each) do
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
UserFixture.reset_all_users
|
let(:admin_user) { User.where(admin: true).first }
|
||||||
|
|
||||||
@normal_user = UserFixture.normal_user
|
before do
|
||||||
@admin_user = UserFixture.admin_user
|
UserFixture.reset_all_users
|
||||||
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/R4-A1-SQL-Injection-Concatentation" do
|
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/R5-A1-SQL-Injection-Concatentation" do
|
||||||
expect(@admin_user.admin).to be_truthy
|
expect(admin_user.admin).to be_truthy
|
||||||
|
|
||||||
login(@normal_user)
|
login(normal_user)
|
||||||
|
|
||||||
visit "/users/#{@normal_user.id}/account_settings"
|
|
||||||
|
|
||||||
|
visit "/users/#{normal_user.id}/account_settings"
|
||||||
within("#account_edit") do
|
within("#account_edit") do
|
||||||
fill_in "Email", with: "joe.admin@schmoe.com"
|
fill_in "Email", with: "joe.admin@schmoe.com"
|
||||||
fill_in "user_password", with: "H4cketyhack"
|
fill_in "user_password", with: "hacketyhack"
|
||||||
fill_in "user_password_confirmation", with: "H4cketyhack"
|
fill_in "user_password_confirmation", with: "hacketyhack"
|
||||||
|
|
||||||
# this is a hidden field, so cannot use fill_in to access it.
|
# this is a hidden field, so cannot use fill_in to access it.
|
||||||
find(:xpath, "//input[@id='user_id']", visible: false).set "8' OR admin='t') --"
|
find(:xpath, "//input[@id='user_id']", visible: false).set "8' OR admin='t') --"
|
||||||
end
|
end
|
||||||
click_on "Submit"
|
click_on "Submit"
|
||||||
|
|
||||||
pending if verifying_fixed?
|
admin_user = User.where(admin: true).first
|
||||||
@admin_user = User.where("admin='t'").first
|
expect(admin_user.email).not_to eq("joe.admin@schmoe.com")
|
||||||
expect(@admin_user.email).to eq("joe.admin@schmoe.com")
|
|
||||||
expect(@admin_user.admin).to eq(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A1-SQL-Injection-Interpolation", js: true do
|
|
||||||
login(@normal_user)
|
|
||||||
Analytics.create!(ip_address: "::1")
|
|
||||||
|
|
||||||
visit "/admin/1/analytics"
|
|
||||||
|
|
||||||
within("#analytics_search") do
|
|
||||||
fill_in "ip", with: "::1"
|
|
||||||
check "field_user_agent"
|
|
||||||
payload = "(select group_concat(password) from users where admin='t')"
|
|
||||||
|
|
||||||
page.execute_script "$('#field_user_agent').attr('name', \"field[#{payload}]\");"
|
|
||||||
page.execute_script "$('#analytics_search').submit();"
|
|
||||||
end
|
|
||||||
|
|
||||||
pending if verifying_fixed?
|
|
||||||
expect(page).to have_css(".dataTable.custom")
|
|
||||||
expect(page.source).to include(@admin_user.password)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,23 +2,24 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "unvalidated redirect" do
|
feature "unvalidated redirect" do
|
||||||
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
|
||||||
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A10-Unvalidated-Redirects-and-Forwards-(redirect_to)", js: true do
|
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A10-Unvalidated-Redirects-and-Forwards-(redirect_to)", js: true do
|
||||||
visit "/?url=http://example.com/do/evil/things"
|
visit "/?url=http://example.com/do/evil/things"
|
||||||
|
|
||||||
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
|
fill_in "password", with: normal_user.clear_password
|
||||||
end
|
end
|
||||||
within(".actions") do
|
within(".actions") do
|
||||||
click_on "Login"
|
click_on "Login"
|
||||||
end
|
end
|
||||||
|
|
||||||
pending if verifying_fixed?
|
expect(current_url).to eq("/dashboard/home")
|
||||||
expect(current_url).to eq("http://example.com/do/evil/things")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,16 +2,19 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "url access" do
|
feature "url access" do
|
||||||
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
|
||||||
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A7-Missing-Function-Level-Access-Control--(Admin-Controller)", js: true do
|
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A7-Missing-Function-Level-Access-Control--(Admin-Controller)", js: true do
|
||||||
login @normal_user
|
login(normal_user)
|
||||||
|
|
||||||
visit "/admin/1/dashboard"
|
visit "/admin/1/dashboard"
|
||||||
pending if verifying_fixed?
|
|
||||||
expect(current_path).to eq("/admin/1/dashboard")
|
expect(current_path).to eq("/")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,30 +2,33 @@
|
|||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
feature "xss" do
|
feature "xss" do
|
||||||
before do
|
let(:normal_user) { UserFixture.normal_user }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
UserFixture.reset_all_users
|
UserFixture.reset_all_users
|
||||||
@normal_user = UserFixture.normal_user
|
|
||||||
|
pending unless verifying_fixed?
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A3-Cross-Site-Scripting", js: true do
|
scenario "attack\nTutorial: https://github.com/OWASP/railsgoat/wiki/A3-Cross-Site-Scripting", js: true do
|
||||||
login @normal_user
|
login(normal_user)
|
||||||
|
|
||||||
visit "/users/#{@normal_user.id}/account_settings"
|
visit "/users/#{normal_user.id}/account_settings"
|
||||||
within("#account_edit") do
|
within("#account_edit") do
|
||||||
fill_in "First name", with: "<script>$(function() { $('div input.btn').val('RailsGoat h4x0r3d') } )</script>"
|
fill_in "First name", with: "<script>$(function() { $('div input.btn').val('RailsGoat h4x0r3d') } )</script>"
|
||||||
|
|
||||||
# password gets screwed up if you don't re-submit - need to fix
|
# password gets screwed up if you don't re-submit - need to fix
|
||||||
fill_in "user_password", with: @normal_user.clear_password
|
fill_in "user_password", with: normal_user.clear_password
|
||||||
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"
|
||||||
|
|
||||||
sleep(1)
|
sleep(1)
|
||||||
|
|
||||||
visit "/users/#{@normal_user.id}/account_settings"
|
visit "/users/#{normal_user.id}/account_settings"
|
||||||
|
|
||||||
pending if verifying_fixed?
|
|
||||||
expect(find("#submit_button").value).to eq("RailsGoat h4x0r3d")
|
expect(find("#submit_button").value).not_to include("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.
|
||||||
|
|||||||
Reference in New Issue
Block a user