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,78 @@
|
|
|
1
|
+
module Scanny
|
|
2
|
+
module Checks
|
|
3
|
+
# Check for logger methods that are called with request params or
|
|
4
|
+
# a dynamic string. This allows us to avoid executing dangerous code.
|
|
5
|
+
class XssLoggerCheck < Check
|
|
6
|
+
def pattern
|
|
7
|
+
[
|
|
8
|
+
pattern_logger_with_params,
|
|
9
|
+
pattern_dynamic_string,
|
|
10
|
+
].join("|")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def check(node)
|
|
14
|
+
issue :low, warning_message, :cwe => [20, 79]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def warning_message
|
|
20
|
+
"Assigning request parameters into logger can lead to XSS issues."
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# logger(params[:password])
|
|
24
|
+
# logger("User password: #{params[:password]} is...")
|
|
25
|
+
def pattern_logger_with_params
|
|
26
|
+
<<-EOT
|
|
27
|
+
SendWithArguments<
|
|
28
|
+
arguments = ActualArguments<
|
|
29
|
+
array = [
|
|
30
|
+
any*,
|
|
31
|
+
SendWithArguments<
|
|
32
|
+
name = :[],
|
|
33
|
+
receiver = Send<name = :params>
|
|
34
|
+
>
|
|
35
|
+
|
|
|
36
|
+
DynamicString<
|
|
37
|
+
array = [
|
|
38
|
+
any*,
|
|
39
|
+
ToString<
|
|
40
|
+
value = SendWithArguments<
|
|
41
|
+
name = :[],
|
|
42
|
+
receiver = Send<name = :params>
|
|
43
|
+
>
|
|
44
|
+
>,
|
|
45
|
+
any*
|
|
46
|
+
]
|
|
47
|
+
>,
|
|
48
|
+
any*
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
>,
|
|
52
|
+
name = :logger
|
|
53
|
+
>
|
|
54
|
+
EOT
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# logger "#{secure_data}"
|
|
58
|
+
def pattern_dynamic_string
|
|
59
|
+
<<-EOT
|
|
60
|
+
SendWithArguments<
|
|
61
|
+
arguments = ActualArguments<
|
|
62
|
+
array = [
|
|
63
|
+
DynamicString<
|
|
64
|
+
array = [
|
|
65
|
+
any*,
|
|
66
|
+
ToString,
|
|
67
|
+
any*
|
|
68
|
+
]
|
|
69
|
+
>
|
|
70
|
+
]
|
|
71
|
+
>,
|
|
72
|
+
name = :logger
|
|
73
|
+
>
|
|
74
|
+
EOT
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Scanny
|
|
2
|
+
module Checks
|
|
3
|
+
# Check for methods mark_as_xss_protected and mark_methods_as_xss_safe
|
|
4
|
+
# that are called and can mark dangerous string as safe for html.
|
|
5
|
+
class XssMarkCheck < Check
|
|
6
|
+
def pattern
|
|
7
|
+
[
|
|
8
|
+
pattern_mark_as_safe,
|
|
9
|
+
pattern_xss_safe,
|
|
10
|
+
pattern_mark_methods_as_xss_safe
|
|
11
|
+
].join("|")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def check(node)
|
|
15
|
+
issue :info, warning_message
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def warning_message
|
|
21
|
+
"Marking string as safe can lead to XSS issues."
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# xss_safe()
|
|
25
|
+
def pattern_xss_safe
|
|
26
|
+
"Send<name = :xss_safe>"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# mark_as_xss_protected()
|
|
30
|
+
def pattern_mark_as_safe
|
|
31
|
+
<<-EOT
|
|
32
|
+
Send<name =
|
|
33
|
+
:mark_as_xss_protected |
|
|
34
|
+
:to_s_xss_protected
|
|
35
|
+
>
|
|
36
|
+
EOT
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def pattern_mark_methods_as_xss_safe
|
|
40
|
+
<<-EOT
|
|
41
|
+
SendWithArguments<name = :mark_methods_as_xss_safe>
|
|
42
|
+
|
|
|
43
|
+
Send<name = :mark_methods_as_xss_safe>
|
|
44
|
+
EOT
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Scanny
|
|
2
|
+
module Checks
|
|
3
|
+
# Checks for send_* methods that are called with :disposition => 'inline'.
|
|
4
|
+
# This can lead to download of private files from a server or to a XSS issue.
|
|
5
|
+
class XssSendCheck < Check
|
|
6
|
+
def pattern
|
|
7
|
+
[
|
|
8
|
+
pattern_send,
|
|
9
|
+
pattern_send_with_param
|
|
10
|
+
].join("|")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def check(node)
|
|
14
|
+
if Machete.matches?(node, pattern_send)
|
|
15
|
+
issue :medium, warning_message, :cwe => [79, 115, 200]
|
|
16
|
+
elsif Machete.matches?(node, pattern_send_with_param)
|
|
17
|
+
issue :high, warning_message, :cwe => 201
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def warning_message
|
|
24
|
+
"Send file or data to client in \"inline\" " +
|
|
25
|
+
"mode or with param can lead to XSS issues."
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# send_file "file.txt", :disposition => "inline"
|
|
29
|
+
# send_data "file.txt", :disposition => "inline"
|
|
30
|
+
def pattern_send
|
|
31
|
+
<<-EOT
|
|
32
|
+
SendWithArguments<
|
|
33
|
+
name = :send_file | :send_data,
|
|
34
|
+
arguments = ActualArguments<
|
|
35
|
+
array = [
|
|
36
|
+
any,
|
|
37
|
+
HashLiteral<
|
|
38
|
+
array = [
|
|
39
|
+
any{even},
|
|
40
|
+
SymbolLiteral<value = :disposition>,
|
|
41
|
+
StringLiteral<string = "inline">,
|
|
42
|
+
any{even}
|
|
43
|
+
]
|
|
44
|
+
>
|
|
45
|
+
]
|
|
46
|
+
>
|
|
47
|
+
>
|
|
48
|
+
EOT
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def pattern_send_with_param
|
|
52
|
+
<<-EOT
|
|
53
|
+
SendWithArguments<
|
|
54
|
+
name = :send_file | :send_data,
|
|
55
|
+
arguments = ActualArguments<
|
|
56
|
+
array = [
|
|
57
|
+
any*,
|
|
58
|
+
SendWithArguments<
|
|
59
|
+
name = :[],
|
|
60
|
+
receiver = Send<name = :params>
|
|
61
|
+
>,
|
|
62
|
+
any*
|
|
63
|
+
]
|
|
64
|
+
>
|
|
65
|
+
>
|
|
66
|
+
EOT
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/scanny/cli.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Scanny
|
|
2
|
+
module CLI
|
|
3
|
+
def build_paths
|
|
4
|
+
paths = ARGV.map do |path|
|
|
5
|
+
path += "/**/*.rb" if File.directory?(path)
|
|
6
|
+
path
|
|
7
|
+
end
|
|
8
|
+
paths << "./app/**/*.rb" if paths.size == 0
|
|
9
|
+
|
|
10
|
+
paths.map { |path| path.gsub('//', '/') }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def require_checks(checks)
|
|
14
|
+
checks = checks.to_s.split(",").map(&:strip)
|
|
15
|
+
|
|
16
|
+
checks.each do |directory|
|
|
17
|
+
Dir[directory + "/**/*.rb"].each do |file|
|
|
18
|
+
require File.expand_path(file, Dir.pwd)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def runner_with_custom_checks(runner, disabled_checks, strict = false)
|
|
24
|
+
disabled_checks = disabled_checks.to_s.split(",").map(&:strip)
|
|
25
|
+
|
|
26
|
+
runner.checks.reject! do |check|
|
|
27
|
+
disabled_checks.any? { |ch| check.class.name == ch } ||
|
|
28
|
+
(check.strict? && !strict)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
runner
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def use_parser(version)
|
|
35
|
+
return unless version
|
|
36
|
+
case version
|
|
37
|
+
when '18'
|
|
38
|
+
Rubinius::Melbourne
|
|
39
|
+
when '19'
|
|
40
|
+
Rubinius::Melbourne19
|
|
41
|
+
else
|
|
42
|
+
$stderr.puts "I can not recognize the version of the parser: #{version}"
|
|
43
|
+
exit 2
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/scanny/issue.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Scanny
|
|
2
|
+
class Issue
|
|
3
|
+
attr_reader :file, :line, :impact, :message, :cwe
|
|
4
|
+
|
|
5
|
+
def initialize(file, line, impact, message, cwe = nil)
|
|
6
|
+
@file, @line, @impact, @message, @cwe = file, line, impact, message, cwe
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def ==(other)
|
|
10
|
+
other.instance_of?(self.class) &&
|
|
11
|
+
@file == other.file &&
|
|
12
|
+
@line == other.line &&
|
|
13
|
+
@impact == other.impact &&
|
|
14
|
+
@message == other.message &&
|
|
15
|
+
@cwe == other.cwe
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
cwe_suffix = if @cwe
|
|
20
|
+
" (" + Array(@cwe).map { |cwe| "CWE-#{cwe}" }.join(", ") + ")"
|
|
21
|
+
else
|
|
22
|
+
""
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
"[#{@impact}] #{@file}:#{@line}: #{@message}#{cwe_suffix}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/tasklib'
|
|
3
|
+
|
|
4
|
+
module Scanny
|
|
5
|
+
class RakeTask < ::Rake::TaskLib
|
|
6
|
+
# name of rake task
|
|
7
|
+
attr_accessor :name
|
|
8
|
+
# paths to custom checks
|
|
9
|
+
attr_accessor :include
|
|
10
|
+
# list of disabled checks
|
|
11
|
+
attr_accessor :disable
|
|
12
|
+
# output format
|
|
13
|
+
attr_accessor :format
|
|
14
|
+
# strict mode
|
|
15
|
+
attr_accessor :strict
|
|
16
|
+
# custom path to scan
|
|
17
|
+
attr_accessor :path
|
|
18
|
+
# raise exception on error
|
|
19
|
+
attr_accessor :fail_on_error
|
|
20
|
+
# ruby mode
|
|
21
|
+
attr_accessor :ruby_mode
|
|
22
|
+
|
|
23
|
+
def initialize(name=:scanny)
|
|
24
|
+
@name = name
|
|
25
|
+
@include = []
|
|
26
|
+
@disable = []
|
|
27
|
+
@format = nil
|
|
28
|
+
@strict = nil
|
|
29
|
+
@path = nil
|
|
30
|
+
@fail_on_error = nil
|
|
31
|
+
@ruby_mode = nil
|
|
32
|
+
|
|
33
|
+
yield self if block_given?
|
|
34
|
+
define
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def define
|
|
38
|
+
desc("Run scanny security scanner")
|
|
39
|
+
|
|
40
|
+
task name do
|
|
41
|
+
cmd = ["scanny"]
|
|
42
|
+
cmd << ["-i"] + [@include] unless @include.empty?
|
|
43
|
+
cmd << ["-d"] + [@disable] unless @disable.empty?
|
|
44
|
+
cmd << ["-f #{@format}"] if @format
|
|
45
|
+
cmd << ["-s"] if @strict
|
|
46
|
+
cmd << ["-m #{@ruby_mode}"] if @ruby_mode
|
|
47
|
+
cmd << [@path] if @path
|
|
48
|
+
cmd = cmd.flatten.join(" ")
|
|
49
|
+
|
|
50
|
+
unless system(cmd)
|
|
51
|
+
raise("Command #{cmd} failed") if fail_on_error
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Scanny
|
|
2
|
+
module Reporters
|
|
3
|
+
class Reporter
|
|
4
|
+
attr_accessor :file, :checks_performed, :nodes_inspected, :issues
|
|
5
|
+
|
|
6
|
+
def initialize(arguments = {})
|
|
7
|
+
arguments.each do |key, value|
|
|
8
|
+
instance_variable_set("@#{key}", value) unless value.nil?
|
|
9
|
+
end
|
|
10
|
+
set_default_values!
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def set_default_values!
|
|
16
|
+
@check_performed ||= 0
|
|
17
|
+
@nodes_inspected ||= 0
|
|
18
|
+
@issues ||= []
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require_relative 'reporter'
|
|
2
|
+
|
|
3
|
+
module Scanny
|
|
4
|
+
module Reporters
|
|
5
|
+
class SimpleReporter < Reporter
|
|
6
|
+
def report
|
|
7
|
+
string = "#{file} [#{checks_performed} checks done | "
|
|
8
|
+
string += "#{nodes_inspected} nodes inspected | #{issues.size} issues]"
|
|
9
|
+
|
|
10
|
+
issues.each do |issue|
|
|
11
|
+
string += "\n - #{issue.to_s}"
|
|
12
|
+
end
|
|
13
|
+
puts string unless issues.empty?
|
|
14
|
+
|
|
15
|
+
string
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require_relative 'reporter'
|
|
2
|
+
require 'rexml/document'
|
|
3
|
+
|
|
4
|
+
module Scanny
|
|
5
|
+
module Reporters
|
|
6
|
+
class XMLReporter < Reporter
|
|
7
|
+
|
|
8
|
+
def initialize(*)
|
|
9
|
+
prepare_reports_directory
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def report
|
|
14
|
+
out = ""
|
|
15
|
+
doc = REXML::Document.new
|
|
16
|
+
|
|
17
|
+
testsuite = REXML::Element.new("testsuite")
|
|
18
|
+
testsuite.add_attributes('assertions' => nodes_inspected.to_s,
|
|
19
|
+
'errors' => issues.size.to_s,
|
|
20
|
+
'skipped' => '0',
|
|
21
|
+
'tests' => checks_performed.to_s,
|
|
22
|
+
'failures' => '0',
|
|
23
|
+
'name' => file)
|
|
24
|
+
#TODO: track time?
|
|
25
|
+
|
|
26
|
+
issues.each do |issue|
|
|
27
|
+
testcase = REXML::Element.new 'testcase'
|
|
28
|
+
testcase.add_attributes("name" => "#{issue.file}:#{issue.line}")
|
|
29
|
+
|
|
30
|
+
error = REXML::Element.new 'error'
|
|
31
|
+
error.add_attributes('type' => issue.impact.to_s,
|
|
32
|
+
'message' => issue.message)
|
|
33
|
+
error.text = issue.to_s
|
|
34
|
+
|
|
35
|
+
testcase.add_element error
|
|
36
|
+
testsuite.add_element testcase
|
|
37
|
+
end
|
|
38
|
+
testsuite.add_element REXML::Element.new("system-out")
|
|
39
|
+
testsuite.add_element REXML::Element.new("system-err")
|
|
40
|
+
|
|
41
|
+
doc << testsuite
|
|
42
|
+
doc.write(out, 2)
|
|
43
|
+
File.open(output, "w") { |f| f.write(out) }
|
|
44
|
+
|
|
45
|
+
out
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def output
|
|
51
|
+
file_name = file.gsub('/', '\\')
|
|
52
|
+
"reports/Test-#{file_name}.xml"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def prepare_reports_directory
|
|
56
|
+
if File.exists?('reports')
|
|
57
|
+
puts "Removing 'reports' directory"
|
|
58
|
+
FileUtils.rm_rf 'reports'
|
|
59
|
+
end
|
|
60
|
+
FileUtils.mkdir 'reports'
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|