scanny 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/Gemfile +11 -0
- data/LICENSE +23 -0
- data/README.md +185 -0
- data/Rakefile +5 -0
- data/bin/scanny +61 -0
- data/lib/scanny.rb +12 -0
- data/lib/scanny/checks/access_control_check.rb +52 -0
- data/lib/scanny/checks/backticks_check.rb +18 -0
- data/lib/scanny/checks/before_filters_check.rb +35 -0
- data/lib/scanny/checks/check.rb +33 -0
- data/lib/scanny/checks/csrf_check.rb +19 -0
- data/lib/scanny/checks/denial_of_service_check.rb +42 -0
- data/lib/scanny/checks/file_open_check.rb +46 -0
- data/lib/scanny/checks/frameworks_check.rb +24 -0
- data/lib/scanny/checks/helpers.rb +28 -0
- data/lib/scanny/checks/http_basic_auth_check.rb +39 -0
- data/lib/scanny/checks/http_header/header_injection_check.rb +38 -0
- data/lib/scanny/checks/http_redirect_check.rb +37 -0
- data/lib/scanny/checks/http_request_check.rb +74 -0
- data/lib/scanny/checks/http_usage_check.rb +31 -0
- data/lib/scanny/checks/information_leak_check.rb +55 -0
- data/lib/scanny/checks/input_filtering_check.rb +39 -0
- data/lib/scanny/checks/insecure_config/set_rails_env_check.rb +24 -0
- data/lib/scanny/checks/insecure_config/set_secret_check.rb +25 -0
- data/lib/scanny/checks/insecure_config/set_session_key_check.rb +23 -0
- data/lib/scanny/checks/insecure_method/eval_method_check.rb +26 -0
- data/lib/scanny/checks/insecure_method/marshal_check.rb +33 -0
- data/lib/scanny/checks/insecure_method/system_method_check.rb +46 -0
- data/lib/scanny/checks/mass_assignment_check.rb +48 -0
- data/lib/scanny/checks/random_numbers_check.rb +54 -0
- data/lib/scanny/checks/redirect_with_params_check.rb +48 -0
- data/lib/scanny/checks/regexp_check.rb +23 -0
- data/lib/scanny/checks/reset_session_check.rb +24 -0
- data/lib/scanny/checks/session/access_to_session_check.rb +49 -0
- data/lib/scanny/checks/session/session_secure_check.rb +47 -0
- data/lib/scanny/checks/shell_expanding_methods_check.rb +54 -0
- data/lib/scanny/checks/skip_before_filters_check.rb +41 -0
- data/lib/scanny/checks/sql_injection/find_method_check.rb +81 -0
- data/lib/scanny/checks/sql_injection/find_method_with_dynamic_string_check.rb +43 -0
- data/lib/scanny/checks/sql_injection/find_method_with_params_check.rb +80 -0
- data/lib/scanny/checks/sql_injection/sanitize_sql_check.rb +25 -0
- data/lib/scanny/checks/sql_injection/sql_check.rb +14 -0
- data/lib/scanny/checks/sql_injection/string_interpolation_with_params_check.rb +39 -0
- data/lib/scanny/checks/ssl/verify_check.rb +53 -0
- data/lib/scanny/checks/ssl/verify_peer_check.rb +37 -0
- data/lib/scanny/checks/system_tools/gpg_usage_check.rb +51 -0
- data/lib/scanny/checks/system_tools/sudo_check.rb +24 -0
- data/lib/scanny/checks/system_tools/tar_check.rb +24 -0
- data/lib/scanny/checks/system_tools/tar_commands_check.rb +27 -0
- data/lib/scanny/checks/system_tools/unzip_check.rb +30 -0
- data/lib/scanny/checks/temp_file_open_check.rb +57 -0
- data/lib/scanny/checks/user_find_check.rb +40 -0
- data/lib/scanny/checks/validates_check.rb +32 -0
- data/lib/scanny/checks/verify_check.rb +44 -0
- data/lib/scanny/checks/xss/xss_flash_check.rb +70 -0
- data/lib/scanny/checks/xss/xss_logger_check.rb +78 -0
- data/lib/scanny/checks/xss/xss_mark_check.rb +48 -0
- data/lib/scanny/checks/xss/xss_send_check.rb +70 -0
- data/lib/scanny/cli.rb +47 -0
- data/lib/scanny/issue.rb +28 -0
- data/lib/scanny/rake_task.rb +56 -0
- data/lib/scanny/reporters.rb +3 -0
- data/lib/scanny/reporters/reporter.rb +22 -0
- data/lib/scanny/reporters/simple_reporter.rb +19 -0
- data/lib/scanny/reporters/xml_reporter.rb +64 -0
- data/lib/scanny/ruby_version_check.rb +15 -0
- data/lib/scanny/runner.rb +90 -0
- data/scanny.gemspec +22 -0
- data/spec/scanny/check_spec.rb +22 -0
- data/spec/scanny/checks/access_control_check_spec.rb +43 -0
- data/spec/scanny/checks/backticks_check_spec.rb +22 -0
- data/spec/scanny/checks/before_filters_check_spec.rb +45 -0
- data/spec/scanny/checks/csrf_check_spec.rb +16 -0
- data/spec/scanny/checks/denial_of_service_check_spec.rb +28 -0
- data/spec/scanny/checks/file_open_check_spec.rb +22 -0
- data/spec/scanny/checks/frameworks_check_spec.rb +16 -0
- data/spec/scanny/checks/http_basic_auth_check_spec.rb +20 -0
- data/spec/scanny/checks/http_header/header_injection_check_spec.rb +21 -0
- data/spec/scanny/checks/http_redirect_check_spec.rb +15 -0
- data/spec/scanny/checks/http_request_check_spec.rb +37 -0
- data/spec/scanny/checks/http_usage_check_spec.rb +20 -0
- data/spec/scanny/checks/information_leak_check_spec.rb +32 -0
- data/spec/scanny/checks/input_filtering_check_spec.rb +19 -0
- data/spec/scanny/checks/insecure_config/set_rails_env_check_spec.rb +17 -0
- data/spec/scanny/checks/insecure_config/set_secret_check_spec.rb +22 -0
- data/spec/scanny/checks/insecure_config/set_session_key_check_spec.rb +21 -0
- data/spec/scanny/checks/insecure_method/eval_method_check_spec.rb +22 -0
- data/spec/scanny/checks/insecure_method/marshal_check_spec.rb +26 -0
- data/spec/scanny/checks/insecure_method/system_method_check_spec.rb +33 -0
- data/spec/scanny/checks/mass_assignment_check_spec.rb +30 -0
- data/spec/scanny/checks/random_numbers_check_spec.rb +41 -0
- data/spec/scanny/checks/redirect_with_params_check_spec.rb +24 -0
- data/spec/scanny/checks/regexp_check_spec.rb +22 -0
- data/spec/scanny/checks/reset_session_check_spec.rb +15 -0
- data/spec/scanny/checks/session/access_to_session_check_spec.rb +29 -0
- data/spec/scanny/checks/session/session_secure_check_spec.rb +22 -0
- data/spec/scanny/checks/shell_expanding_methods_check_spec.rb +67 -0
- data/spec/scanny/checks/skip_before_filters_check_spec.rb +81 -0
- data/spec/scanny/checks/sql_injection/find_method_check_spec.rb +62 -0
- data/spec/scanny/checks/sql_injection/find_method_with_dynamic_string_check_spec.rb +27 -0
- data/spec/scanny/checks/sql_injection/find_method_with_params_check_spec.rb +93 -0
- data/spec/scanny/checks/sql_injection/sanitize_sql_check_spec.rb +16 -0
- data/spec/scanny/checks/sql_injection/string_interpolation_with_params_check_spec.rb +18 -0
- data/spec/scanny/checks/ssl/verify_check_spec.rb +25 -0
- data/spec/scanny/checks/ssl/verify_peer_check_spec.rb +17 -0
- data/spec/scanny/checks/system_tools/gpg_usage_check_spec.rb +43 -0
- data/spec/scanny/checks/system_tools/sudo_check_spec.rb +24 -0
- data/spec/scanny/checks/system_tools/tar_check_spec.rb +20 -0
- data/spec/scanny/checks/system_tools/tar_commands_check_spec.rb +41 -0
- data/spec/scanny/checks/system_tools/unizp_check_spec.rb +29 -0
- data/spec/scanny/checks/temp_file_open_check_spec.rb +22 -0
- data/spec/scanny/checks/user_find_check_spec.rb +22 -0
- data/spec/scanny/checks/validates_check_spec.rb +19 -0
- data/spec/scanny/checks/verify_check_spec.rb +27 -0
- data/spec/scanny/checks/xss/xss_flash_check_spec.rb +22 -0
- data/spec/scanny/checks/xss/xss_logger_check_spec.rb +24 -0
- data/spec/scanny/checks/xss/xss_mark_check_spec.rb +31 -0
- data/spec/scanny/checks/xss/xss_send_check_spec.rb +34 -0
- data/spec/scanny/cli_spec.rb +167 -0
- data/spec/scanny/issue_spec.rb +82 -0
- data/spec/scanny/rake_taks_spec.rb +82 -0
- data/spec/scanny/reporters/reporter_spec.rb +24 -0
- data/spec/scanny/reporters/simple_reporter_spec.rb +48 -0
- data/spec/scanny/reporters/xml_reporter_spec.rb +52 -0
- data/spec/scanny/ruby_version_check_spec.rb +24 -0
- data/spec/scanny/runner_spec.rb +128 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/aruba.rb +4 -0
- data/spec/support/check_spec_helpers.rb +5 -0
- data/spec/support/checks/extend_test_check.rb +11 -0
- data/spec/support/checks/test_check.rb +15 -0
- data/spec/support/checks/test_strict_check.rb +17 -0
- data/spec/support/const_spec_helpers.rb +36 -0
- data/spec/support/matchers/check_matcher.rb +43 -0
- data/spec/support/matchers/xpath_matcher.rb +30 -0
- data/spec/support/mock_task.rb +43 -0
- metadata +242 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
unless defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx" && RUBY_VERSION >= '1.9'
|
|
2
|
+
desc = defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})"
|
|
3
|
+
abort <<-end_message
|
|
4
|
+
|
|
5
|
+
Scanny requires Rubinius in 1.9 mode.
|
|
6
|
+
|
|
7
|
+
You're running
|
|
8
|
+
#{desc}
|
|
9
|
+
|
|
10
|
+
Please change your Ruby implementation to continue.
|
|
11
|
+
|
|
12
|
+
end_message
|
|
13
|
+
|
|
14
|
+
raise abort
|
|
15
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require "yaml"
|
|
2
|
+
require "machete"
|
|
3
|
+
require "ostruct"
|
|
4
|
+
|
|
5
|
+
module Scanny
|
|
6
|
+
class Runner
|
|
7
|
+
attr_reader :checks, :checks_data, :file, :parser
|
|
8
|
+
|
|
9
|
+
def initialize(*checks)
|
|
10
|
+
options = checks.last.is_a?(Hash) ? checks.pop : {}
|
|
11
|
+
|
|
12
|
+
if checks.empty?
|
|
13
|
+
@checks = check_classes
|
|
14
|
+
else
|
|
15
|
+
@checks = checks
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
@checks_data = []
|
|
19
|
+
@parser = options[:parser] || Rubinius::Melbourne19
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def check(file, input)
|
|
23
|
+
ast = parser.new("(eval)", 1).parse_string(input)
|
|
24
|
+
ignored_lines = extract_ignored_lines(input)
|
|
25
|
+
checks_performed = 0
|
|
26
|
+
nodes_inspected = 0
|
|
27
|
+
issues = []
|
|
28
|
+
|
|
29
|
+
@checks.each do |check|
|
|
30
|
+
nodes_to_inspect = Machete.find(ast, check.compiled_pattern)
|
|
31
|
+
checks_performed += 1 unless nodes_to_inspect.empty?
|
|
32
|
+
nodes_inspected += nodes_to_inspect.size
|
|
33
|
+
|
|
34
|
+
nodes_to_inspect.each do |node|
|
|
35
|
+
issues += check.visit(file, node)
|
|
36
|
+
end
|
|
37
|
+
issues.reject! { |i| ignored_lines.include?(i.line) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
:issues => issues,
|
|
42
|
+
:checks_performed => checks_performed,
|
|
43
|
+
:nodes_inspected => nodes_inspected,
|
|
44
|
+
:file => file
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def check_file(file)
|
|
49
|
+
@file = file
|
|
50
|
+
@checks_data << check(file, File.read(file))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def check_files(*files)
|
|
54
|
+
files.each { |f| check_file(f) }
|
|
55
|
+
end
|
|
56
|
+
alias :run :check_files
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def check_classes
|
|
61
|
+
# Get list of all subclasses of Scanny::Checks::Check.
|
|
62
|
+
classes = []
|
|
63
|
+
ObjectSpace.each_object(Class) do |klass|
|
|
64
|
+
classes << klass if klass < Scanny::Checks::Check
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Filter out classes that are a superclass of some other class in the list.
|
|
68
|
+
# This way only "leaf" classes remain.
|
|
69
|
+
classes.reject! do |klass|
|
|
70
|
+
classes.any? { |c| c < klass }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
classes.map(&:new)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def extract_ignored_lines(input)
|
|
77
|
+
ignored_lines = []
|
|
78
|
+
input.split("\n").each_with_index do |line, i|
|
|
79
|
+
if line =~ /SCANNY_IGNORE(_NEXT(?:_(\d+))?)?/
|
|
80
|
+
if $2
|
|
81
|
+
ignored_lines += ((i + 2)..(i + 1 + $2.to_i)).to_a
|
|
82
|
+
else
|
|
83
|
+
ignored_lines << i + ($1 ? 2 : 1)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
ignored_lines
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
data/scanny.gemspec
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |s|
|
|
4
|
+
s.name = "scanny"
|
|
5
|
+
s.version = '0.1.0'
|
|
6
|
+
s.platform = Gem::Platform::RUBY
|
|
7
|
+
s.authors = ['Thomas Biege', 'Flavio Castelli', 'David Majda', 'Piotr Niełacny']
|
|
8
|
+
s.email = ['thomas@suse.de', 'fcastelli@novell.com', 'dmajda@suse.cz', 'piotr.nielacny@gmail.com']
|
|
9
|
+
s.homepage = "https://github.com/openSUSE/scanny"
|
|
10
|
+
s.summary = "Ruby security scanner"
|
|
11
|
+
s.description = "Find all security issues affecting your code."
|
|
12
|
+
|
|
13
|
+
s.required_rubygems_version = ">= 1.3.6"
|
|
14
|
+
s.rubyforge_project = "scanny"
|
|
15
|
+
|
|
16
|
+
s.add_dependency "machete", "0.5.0"
|
|
17
|
+
s.add_dependency "docopt", "0.0.4"
|
|
18
|
+
|
|
19
|
+
s.files = `git ls-files`.split("\n")
|
|
20
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
|
21
|
+
s.require_path = 'lib'
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe Check do
|
|
5
|
+
it "reports issues" do
|
|
6
|
+
check = TestCheck.new
|
|
7
|
+
issues = check.visit("unsecure.rb", Rubinius::AST::FixnumLiteral.new(1, 42))
|
|
8
|
+
|
|
9
|
+
issues.should == [
|
|
10
|
+
Scanny::Issue.new("unsecure.rb", 1, :high, "Hey, I found unsecure code!", 42),
|
|
11
|
+
Scanny::Issue.new("unsecure.rb", 1, :high, "Hey, I found more unsecure code!", 43),
|
|
12
|
+
Scanny::Issue.new("unsecure.rb", 1, :low, "OK, this is unsecure too, but not that much")
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "returns compiled pattern" do
|
|
17
|
+
check = TestCheck.new
|
|
18
|
+
compiled_pattern = check.compiled_pattern
|
|
19
|
+
compiled_pattern.should be_kind_of(Machete::Matchers::NodeMatcher)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe AccessControlCheck do
|
|
5
|
+
before :each do
|
|
6
|
+
@runner = Scanny::Runner.new(AccessControlCheck.new)
|
|
7
|
+
@issue = issue(:medium,
|
|
8
|
+
"Using \"params[:id]\" requires proper authorization check.", 285)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "reports \"new\" calls with \"params[:id]\" in the attributes hash correctly" do
|
|
12
|
+
@runner.should check('User.new(:id => params[:id])').with_issue(@issue)
|
|
13
|
+
@runner.should check(
|
|
14
|
+
'User.new(:foo => 42, :id => params[:id], :bar => 43)'
|
|
15
|
+
).with_issue(@issue)
|
|
16
|
+
@runner.should check('User.new(:id => not_params[:id])').without_issues
|
|
17
|
+
@runner.should check('User.new(:id => params[:not_id])').without_issues
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "reports \"create\" calls with \"params[:id]\" in the attributes hash correctly" do
|
|
21
|
+
@runner.should check('User.create(:id => params[:id])').with_issue(@issue)
|
|
22
|
+
@runner.should check(
|
|
23
|
+
'User.create(:foo => 42, :id => params[:id], :bar => 43)'
|
|
24
|
+
).with_issue(@issue)
|
|
25
|
+
@runner.should check('User.create(:id => not_params[:id])').without_issues
|
|
26
|
+
@runner.should check('User.create(:id => params[:not_id])').without_issues
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "reports \"delete\" calls with \"params[:id]\" in the arguments" do
|
|
30
|
+
@runner.should check('User.delete(params[:id])').with_issue(@issue)
|
|
31
|
+
@runner.should check('User.delete(42, params[:id], 43)').with_issue(@issue)
|
|
32
|
+
@runner.should check('User.new(not_params[:id])').without_issues
|
|
33
|
+
@runner.should check('User.new(params[:not_id])').without_issues
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "reports \"destroy\" calls with \"params[:id]\" in the arguments" do
|
|
37
|
+
@runner.should check('User.destroy(params[:id])').with_issue(@issue)
|
|
38
|
+
@runner.should check('User.destroy(42, params[:id], 43)').with_issue(@issue)
|
|
39
|
+
@runner.should check('User.new(not_params[:id])').without_issues
|
|
40
|
+
@runner.should check('User.new(params[:not_id])').without_issues
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe BackticksCheck do
|
|
5
|
+
before :each do
|
|
6
|
+
@runner = Scanny::Runner.new(BackticksCheck.new)
|
|
7
|
+
@issue = issue(:high,
|
|
8
|
+
"Backticks and %x{...} pass the executed command through shell expansion.",
|
|
9
|
+
[88, 78])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "reports backticks correctly" do
|
|
13
|
+
@runner.should check('`ls -l`').with_issue(@issue)
|
|
14
|
+
@runner.should check('`ls #{options}`').with_issue(@issue)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "reports %x{...} correctly" do
|
|
18
|
+
@runner.should check('%x{ls -l}').with_issue(@issue)
|
|
19
|
+
@runner.should check('%x{ls #{options}}').with_issue(@issue)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe BeforeFiltersCheck do
|
|
5
|
+
before :each do
|
|
6
|
+
@runner = Scanny::Runner.new(BeforeFiltersCheck.new)
|
|
7
|
+
@login_required_issue = issue(:info,
|
|
8
|
+
"The \"before_filter\" method with :login_required filter is used.",
|
|
9
|
+
nil)
|
|
10
|
+
@admin_required_issue = issue(:info,
|
|
11
|
+
"The \"before_filter\" method with :admin_required filter is used.",
|
|
12
|
+
nil)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "reports \"before_filter\" with :login_required filter correctly" do
|
|
16
|
+
@runner.should check(
|
|
17
|
+
'before_filter :login_required'
|
|
18
|
+
).with_issue(@login_required_issue)
|
|
19
|
+
@runner.should check(
|
|
20
|
+
'self.before_filter :login_required'
|
|
21
|
+
).with_issue(@login_required_issue)
|
|
22
|
+
@runner.should check('foo.before_filter :login_required').without_issues
|
|
23
|
+
@runner.should check('after_filter :login_required').without_issues
|
|
24
|
+
@runner.should check(
|
|
25
|
+
'before_filter :some_filter, :login_required, :another_filter'
|
|
26
|
+
).with_issue(@login_required_issue)
|
|
27
|
+
@runner.should check('before_filter :some_filter').without_issues
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "reports \"before_filter\" with :admin_required filter correctly" do
|
|
31
|
+
@runner.should check(
|
|
32
|
+
'before_filter :admin_required'
|
|
33
|
+
).with_issue(@admin_required_issue)
|
|
34
|
+
@runner.should check(
|
|
35
|
+
'self.before_filter :admin_required'
|
|
36
|
+
).with_issue(@admin_required_issue)
|
|
37
|
+
@runner.should check('foo.before_filter :admin_required').without_issues
|
|
38
|
+
@runner.should check('after_filter :admin_required').without_issues
|
|
39
|
+
@runner.should check(
|
|
40
|
+
'before_filter :some_filter, :admin_required, :another_filter'
|
|
41
|
+
).with_issue(@admin_required_issue)
|
|
42
|
+
@runner.should check('before_filter :some_filter').without_issues
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe CSRFCheck do
|
|
5
|
+
before :each do
|
|
6
|
+
@runner = Scanny::Runner.new(CSRFCheck.new)
|
|
7
|
+
@issue = issue(:info, "The \"protect_from_forgery\" method is used.", 352)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "reports \"protect_from_forgery\" correctly" do
|
|
11
|
+
@runner.should check('protect_from_forgery').with_issue(@issue)
|
|
12
|
+
@runner.should check('self.protect_from_forgery').with_issue(@issue)
|
|
13
|
+
@runner.should check('foo.protect_from_forgery').without_issues
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe DenialOfServiceCheck do
|
|
5
|
+
before do
|
|
6
|
+
@runner = Scanny::Runner.new(DenialOfServiceCheck.new)
|
|
7
|
+
@message = "Using \"LIKE\" in queries may lead to " +
|
|
8
|
+
"the unavailability of the application"
|
|
9
|
+
@issue = issue(:medium, @message, 400)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "reports \"User.find(:first, :conditions => \"name LIKE '%bob%'\" )\" correctly" do
|
|
13
|
+
@runner.should check("User.find(:first, :conditions => \"name LIKE '%bob%'\" )").
|
|
14
|
+
with_issue(@issue)
|
|
15
|
+
@runner.should check("User.find(:conditions => \"name LIKE '%bob%'\")").
|
|
16
|
+
without_issues
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "reports \"User.find(:first, :limit => \"name LIKE '%bob%'\" )\" correctly" do
|
|
20
|
+
@runner.should check("User.find(:first, :limit => \"name LIKE '%bob%'\" )").
|
|
21
|
+
with_issue(@issue)
|
|
22
|
+
@runner.should check("User.find(:limit => \"name LIKE '%bob%'\")").
|
|
23
|
+
without_issues
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe FileOpenCheck do
|
|
5
|
+
before do
|
|
6
|
+
@runner = Scanny::Runner.new(FileOpenCheck.new)
|
|
7
|
+
@message = "Operations on files in code can lead to" +
|
|
8
|
+
"unauthorized access to data"
|
|
9
|
+
@issue = issue(:info, @message)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "reports \"File.open('/home/app/tmp/file')\" correctly" do
|
|
13
|
+
@runner.should check("File.open('/home/app/tmp/file')").
|
|
14
|
+
with_issue(@issue)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "reports \"FileUtils.chmod(0755, '/usr/bin/ruby')\" correctly" do
|
|
18
|
+
@runner.should check("FileUtils.chmod(0755, '/usr/bin/ruby')").
|
|
19
|
+
with_issue(@issue)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe FrameworksCheck do
|
|
5
|
+
before do
|
|
6
|
+
@runner = Scanny::Runner.new(FrameworksCheck.new)
|
|
7
|
+
@message = "Using the methods from frameworks can lead to security problems"
|
|
8
|
+
@issue = issue(:info, @message)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "reports \"env['HTTP_X_USERNAME']\" correctly" do
|
|
12
|
+
@runner.should check("env['HTTP_X_USERNAME']").with_issue(@issue)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe HTTPBasicAuthCheck do
|
|
5
|
+
before do
|
|
6
|
+
@runner = Scanny::Runner.new(HTTPBasicAuthCheck.new)
|
|
7
|
+
@message = "Basic HTTP authentication can lead to security problems"
|
|
8
|
+
@issue = issue(:info, @message, [301, 718])
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "reports \"Net::HTTPHeader#basic_auth'\" correctly" do
|
|
12
|
+
@runner.should check("basic_auth('user', 'password')").with_issue(@issue)
|
|
13
|
+
@runner.should check("basic_auth").without_issues
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "reports \"HttpAuthentication\" correctly" do
|
|
17
|
+
@runner.should check("HttpAuthentication").with_issue(@issue)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks::HttpHeader
|
|
4
|
+
describe HeaderInjectionCheck do
|
|
5
|
+
before do
|
|
6
|
+
@runner = Scanny::Runner.new(HeaderInjectionCheck.new)
|
|
7
|
+
@message = "Directly use of the HTTP_* headers in code. " +
|
|
8
|
+
"Possible injection vulnerabilities"
|
|
9
|
+
@issue = issue(:medium, @message, [20, 113])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "reports \"env['HTTP_HEADER']\" correctly" do
|
|
13
|
+
@runner.should check("env['HTTP_HEADER']").with_issue(@issue)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "reports \"headers['HTTP_HEADER']\" correctly" do
|
|
17
|
+
@runner.should check("headers['HTTP_HEADER']").with_issue(@issue)
|
|
18
|
+
@runner.should check("headers['NORMAL_HEADER']").without_issues
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe HTTPRedirectCheck do
|
|
5
|
+
before do
|
|
6
|
+
@runner = Scanny::Runner.new(HTTPRedirectCheck.new)
|
|
7
|
+
@message = "HTTP redirects can be emitted by the Application"
|
|
8
|
+
@issue = issue(:medium, @message, 441)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "reports \"require 'open-uri'\" correctly" do
|
|
12
|
+
@runner.should check("require 'open-uri'").with_issue(@issue)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Scanny::Checks
|
|
4
|
+
describe HTTPRequestCheck do
|
|
5
|
+
before do
|
|
6
|
+
@runner = Scanny::Runner.new(HTTPRequestCheck.new)
|
|
7
|
+
@message = "Connecting to the server without encryption " +
|
|
8
|
+
"can facilitate sniffing traffic"
|
|
9
|
+
@issue = issue(:low, @message, 441)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "reports \"Net::HTTP.new('http://example.com/')\" correctly" do
|
|
13
|
+
@runner.should check("Net::HTTP.new('http://example.com/')").
|
|
14
|
+
with_issue(@issue)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "reports \"Net::HTTP::Get.new('http://example.com/')\" correctly" do
|
|
18
|
+
@runner.should check("Net::HTTP::Get.new('http://example.com/')").
|
|
19
|
+
with_issue(@issue)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "reports \"Net::HTTP::Post.new('http://example.com/')\" correctly" do
|
|
23
|
+
@runner.should check("Net::HTTP::Post.new('http://example.com/')").
|
|
24
|
+
with_issue(@issue)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "reports \"Net::HTTP::Method.new('http://example.com/')\" correctly" do
|
|
28
|
+
@runner.should check("Net::HTTP::Method.new('http://example.com/')").
|
|
29
|
+
with_issue(@issue)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "reports \"Net::HTTP::Proxy('proxy.example.com', 8080)\" correctly" do
|
|
33
|
+
@runner.should check("Net::HTTP::Proxy('proxy.example.com', 8080)").
|
|
34
|
+
with_issue(@issue)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|