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.
Files changed (138) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +11 -0
  3. data/LICENSE +23 -0
  4. data/README.md +185 -0
  5. data/Rakefile +5 -0
  6. data/bin/scanny +61 -0
  7. data/lib/scanny.rb +12 -0
  8. data/lib/scanny/checks/access_control_check.rb +52 -0
  9. data/lib/scanny/checks/backticks_check.rb +18 -0
  10. data/lib/scanny/checks/before_filters_check.rb +35 -0
  11. data/lib/scanny/checks/check.rb +33 -0
  12. data/lib/scanny/checks/csrf_check.rb +19 -0
  13. data/lib/scanny/checks/denial_of_service_check.rb +42 -0
  14. data/lib/scanny/checks/file_open_check.rb +46 -0
  15. data/lib/scanny/checks/frameworks_check.rb +24 -0
  16. data/lib/scanny/checks/helpers.rb +28 -0
  17. data/lib/scanny/checks/http_basic_auth_check.rb +39 -0
  18. data/lib/scanny/checks/http_header/header_injection_check.rb +38 -0
  19. data/lib/scanny/checks/http_redirect_check.rb +37 -0
  20. data/lib/scanny/checks/http_request_check.rb +74 -0
  21. data/lib/scanny/checks/http_usage_check.rb +31 -0
  22. data/lib/scanny/checks/information_leak_check.rb +55 -0
  23. data/lib/scanny/checks/input_filtering_check.rb +39 -0
  24. data/lib/scanny/checks/insecure_config/set_rails_env_check.rb +24 -0
  25. data/lib/scanny/checks/insecure_config/set_secret_check.rb +25 -0
  26. data/lib/scanny/checks/insecure_config/set_session_key_check.rb +23 -0
  27. data/lib/scanny/checks/insecure_method/eval_method_check.rb +26 -0
  28. data/lib/scanny/checks/insecure_method/marshal_check.rb +33 -0
  29. data/lib/scanny/checks/insecure_method/system_method_check.rb +46 -0
  30. data/lib/scanny/checks/mass_assignment_check.rb +48 -0
  31. data/lib/scanny/checks/random_numbers_check.rb +54 -0
  32. data/lib/scanny/checks/redirect_with_params_check.rb +48 -0
  33. data/lib/scanny/checks/regexp_check.rb +23 -0
  34. data/lib/scanny/checks/reset_session_check.rb +24 -0
  35. data/lib/scanny/checks/session/access_to_session_check.rb +49 -0
  36. data/lib/scanny/checks/session/session_secure_check.rb +47 -0
  37. data/lib/scanny/checks/shell_expanding_methods_check.rb +54 -0
  38. data/lib/scanny/checks/skip_before_filters_check.rb +41 -0
  39. data/lib/scanny/checks/sql_injection/find_method_check.rb +81 -0
  40. data/lib/scanny/checks/sql_injection/find_method_with_dynamic_string_check.rb +43 -0
  41. data/lib/scanny/checks/sql_injection/find_method_with_params_check.rb +80 -0
  42. data/lib/scanny/checks/sql_injection/sanitize_sql_check.rb +25 -0
  43. data/lib/scanny/checks/sql_injection/sql_check.rb +14 -0
  44. data/lib/scanny/checks/sql_injection/string_interpolation_with_params_check.rb +39 -0
  45. data/lib/scanny/checks/ssl/verify_check.rb +53 -0
  46. data/lib/scanny/checks/ssl/verify_peer_check.rb +37 -0
  47. data/lib/scanny/checks/system_tools/gpg_usage_check.rb +51 -0
  48. data/lib/scanny/checks/system_tools/sudo_check.rb +24 -0
  49. data/lib/scanny/checks/system_tools/tar_check.rb +24 -0
  50. data/lib/scanny/checks/system_tools/tar_commands_check.rb +27 -0
  51. data/lib/scanny/checks/system_tools/unzip_check.rb +30 -0
  52. data/lib/scanny/checks/temp_file_open_check.rb +57 -0
  53. data/lib/scanny/checks/user_find_check.rb +40 -0
  54. data/lib/scanny/checks/validates_check.rb +32 -0
  55. data/lib/scanny/checks/verify_check.rb +44 -0
  56. data/lib/scanny/checks/xss/xss_flash_check.rb +70 -0
  57. data/lib/scanny/checks/xss/xss_logger_check.rb +78 -0
  58. data/lib/scanny/checks/xss/xss_mark_check.rb +48 -0
  59. data/lib/scanny/checks/xss/xss_send_check.rb +70 -0
  60. data/lib/scanny/cli.rb +47 -0
  61. data/lib/scanny/issue.rb +28 -0
  62. data/lib/scanny/rake_task.rb +56 -0
  63. data/lib/scanny/reporters.rb +3 -0
  64. data/lib/scanny/reporters/reporter.rb +22 -0
  65. data/lib/scanny/reporters/simple_reporter.rb +19 -0
  66. data/lib/scanny/reporters/xml_reporter.rb +64 -0
  67. data/lib/scanny/ruby_version_check.rb +15 -0
  68. data/lib/scanny/runner.rb +90 -0
  69. data/scanny.gemspec +22 -0
  70. data/spec/scanny/check_spec.rb +22 -0
  71. data/spec/scanny/checks/access_control_check_spec.rb +43 -0
  72. data/spec/scanny/checks/backticks_check_spec.rb +22 -0
  73. data/spec/scanny/checks/before_filters_check_spec.rb +45 -0
  74. data/spec/scanny/checks/csrf_check_spec.rb +16 -0
  75. data/spec/scanny/checks/denial_of_service_check_spec.rb +28 -0
  76. data/spec/scanny/checks/file_open_check_spec.rb +22 -0
  77. data/spec/scanny/checks/frameworks_check_spec.rb +16 -0
  78. data/spec/scanny/checks/http_basic_auth_check_spec.rb +20 -0
  79. data/spec/scanny/checks/http_header/header_injection_check_spec.rb +21 -0
  80. data/spec/scanny/checks/http_redirect_check_spec.rb +15 -0
  81. data/spec/scanny/checks/http_request_check_spec.rb +37 -0
  82. data/spec/scanny/checks/http_usage_check_spec.rb +20 -0
  83. data/spec/scanny/checks/information_leak_check_spec.rb +32 -0
  84. data/spec/scanny/checks/input_filtering_check_spec.rb +19 -0
  85. data/spec/scanny/checks/insecure_config/set_rails_env_check_spec.rb +17 -0
  86. data/spec/scanny/checks/insecure_config/set_secret_check_spec.rb +22 -0
  87. data/spec/scanny/checks/insecure_config/set_session_key_check_spec.rb +21 -0
  88. data/spec/scanny/checks/insecure_method/eval_method_check_spec.rb +22 -0
  89. data/spec/scanny/checks/insecure_method/marshal_check_spec.rb +26 -0
  90. data/spec/scanny/checks/insecure_method/system_method_check_spec.rb +33 -0
  91. data/spec/scanny/checks/mass_assignment_check_spec.rb +30 -0
  92. data/spec/scanny/checks/random_numbers_check_spec.rb +41 -0
  93. data/spec/scanny/checks/redirect_with_params_check_spec.rb +24 -0
  94. data/spec/scanny/checks/regexp_check_spec.rb +22 -0
  95. data/spec/scanny/checks/reset_session_check_spec.rb +15 -0
  96. data/spec/scanny/checks/session/access_to_session_check_spec.rb +29 -0
  97. data/spec/scanny/checks/session/session_secure_check_spec.rb +22 -0
  98. data/spec/scanny/checks/shell_expanding_methods_check_spec.rb +67 -0
  99. data/spec/scanny/checks/skip_before_filters_check_spec.rb +81 -0
  100. data/spec/scanny/checks/sql_injection/find_method_check_spec.rb +62 -0
  101. data/spec/scanny/checks/sql_injection/find_method_with_dynamic_string_check_spec.rb +27 -0
  102. data/spec/scanny/checks/sql_injection/find_method_with_params_check_spec.rb +93 -0
  103. data/spec/scanny/checks/sql_injection/sanitize_sql_check_spec.rb +16 -0
  104. data/spec/scanny/checks/sql_injection/string_interpolation_with_params_check_spec.rb +18 -0
  105. data/spec/scanny/checks/ssl/verify_check_spec.rb +25 -0
  106. data/spec/scanny/checks/ssl/verify_peer_check_spec.rb +17 -0
  107. data/spec/scanny/checks/system_tools/gpg_usage_check_spec.rb +43 -0
  108. data/spec/scanny/checks/system_tools/sudo_check_spec.rb +24 -0
  109. data/spec/scanny/checks/system_tools/tar_check_spec.rb +20 -0
  110. data/spec/scanny/checks/system_tools/tar_commands_check_spec.rb +41 -0
  111. data/spec/scanny/checks/system_tools/unizp_check_spec.rb +29 -0
  112. data/spec/scanny/checks/temp_file_open_check_spec.rb +22 -0
  113. data/spec/scanny/checks/user_find_check_spec.rb +22 -0
  114. data/spec/scanny/checks/validates_check_spec.rb +19 -0
  115. data/spec/scanny/checks/verify_check_spec.rb +27 -0
  116. data/spec/scanny/checks/xss/xss_flash_check_spec.rb +22 -0
  117. data/spec/scanny/checks/xss/xss_logger_check_spec.rb +24 -0
  118. data/spec/scanny/checks/xss/xss_mark_check_spec.rb +31 -0
  119. data/spec/scanny/checks/xss/xss_send_check_spec.rb +34 -0
  120. data/spec/scanny/cli_spec.rb +167 -0
  121. data/spec/scanny/issue_spec.rb +82 -0
  122. data/spec/scanny/rake_taks_spec.rb +82 -0
  123. data/spec/scanny/reporters/reporter_spec.rb +24 -0
  124. data/spec/scanny/reporters/simple_reporter_spec.rb +48 -0
  125. data/spec/scanny/reporters/xml_reporter_spec.rb +52 -0
  126. data/spec/scanny/ruby_version_check_spec.rb +24 -0
  127. data/spec/scanny/runner_spec.rb +128 -0
  128. data/spec/spec_helper.rb +10 -0
  129. data/spec/support/aruba.rb +4 -0
  130. data/spec/support/check_spec_helpers.rb +5 -0
  131. data/spec/support/checks/extend_test_check.rb +11 -0
  132. data/spec/support/checks/test_check.rb +15 -0
  133. data/spec/support/checks/test_strict_check.rb +17 -0
  134. data/spec/support/const_spec_helpers.rb +36 -0
  135. data/spec/support/matchers/check_matcher.rb +43 -0
  136. data/spec/support/matchers/xpath_matcher.rb +30 -0
  137. data/spec/support/mock_task.rb +43 -0
  138. metadata +242 -0
@@ -0,0 +1,37 @@
1
+ module Scanny
2
+ module Checks
3
+ module SSL
4
+ class VerifyPeerCheck < Check
5
+ def pattern
6
+ pattern_ssl_verify_peer
7
+ end
8
+
9
+ def check(node)
10
+ issue :info, warning_message
11
+ end
12
+
13
+ private
14
+
15
+ def warning_message
16
+ "Change the value of of VERIFY_PEER" +
17
+ "can lead to faulty accepted certificate"
18
+ end
19
+
20
+ # OpenSSL::SSL::VERIFY_PEER
21
+ def pattern_ssl_verify_peer
22
+ <<-EOT
23
+ ConstantAssignment<
24
+ constant = ScopedConstant<
25
+ name = :VERIFY_PEER,
26
+ parent = ScopedConstant<
27
+ name = :SSL,
28
+ parent = ConstantAccess<name = :OpenSSL>
29
+ >
30
+ >
31
+ >
32
+ EOT
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,51 @@
1
+ module Scanny
2
+ module Checks
3
+ module SystemTools
4
+ class GpgUsageCheck < Check
5
+ include Scanny::Checks::Helpers
6
+
7
+ def pattern
8
+ [
9
+ pattern_gpg_class,
10
+ pattern_gpg_method,
11
+ build_pattern_exec_command('gpg')
12
+ ].join("|")
13
+ end
14
+
15
+ def check(node)
16
+ issue :info, warning_message
17
+ end
18
+
19
+ private
20
+
21
+ def warning_message
22
+ "Using gpg tool in the wrong way can lead to security problems"
23
+ end
24
+
25
+ # GPG.method
26
+ def pattern_gpg_class
27
+ <<-EOT
28
+ Send
29
+ <
30
+ receiver = ConstantAccess<
31
+ name *= /gpg/i
32
+ >
33
+ >
34
+ |
35
+ SendWithArguments
36
+ <
37
+ receiver = ConstantAccess<
38
+ name *= /gpg/i
39
+ >
40
+ >
41
+ EOT
42
+ end
43
+
44
+ # gpg()
45
+ def pattern_gpg_method
46
+ "Send<name *= 'gpg'> | SendWithArguments<name *= 'gpg'>"
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ module Scanny
2
+ module Checks
3
+ module SystemTools
4
+ class SudoCheck < Check
5
+ include Scanny::Checks::Helpers
6
+
7
+ def pattern
8
+ build_pattern_exec_command('sudo')
9
+ end
10
+
11
+ def check(node)
12
+ issue :info, warning_message
13
+ end
14
+
15
+ private
16
+
17
+ def warning_message
18
+ "Using sudo can lead to the execution" +
19
+ "of programs on root administrator rights"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ module Scanny
2
+ module Checks
3
+ module SystemTools
4
+ class TarCheck < Check
5
+ include Scanny::Checks::Helpers
6
+
7
+ def pattern
8
+ build_pattern_exec_command(/tar\s+/)
9
+ end
10
+
11
+ def check(node)
12
+ issue :medium, warning_message, :cwe => 88
13
+ end
14
+
15
+ private
16
+
17
+ def warning_message
18
+ "Tar command can execute dangerous operations on files" +
19
+ "and can travel through directories"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ module Scanny
2
+ module Checks
3
+ module SystemTools
4
+ class TarCommandsCheck < Check
5
+ include Scanny::Checks::Helpers
6
+
7
+ def pattern
8
+ [
9
+ build_pattern_exec_command(/tar.*\-\-to\-command/),
10
+ build_pattern_exec_command(/tar.*\-\-rmt\-command/),
11
+ build_pattern_exec_command(/tar.*\-\-rsh\-command/)
12
+ ].join("|")
13
+ end
14
+
15
+ def check(node)
16
+ issue :high, warning_message, :cwe => 88
17
+ end
18
+
19
+ private
20
+
21
+ def warning_message
22
+ "Tar command has an option that allows to run external programs"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ module Scanny
2
+ module Checks
3
+ module SystemTools
4
+ class UnzipCheck < Check
5
+ include Scanny::Checks::Helpers
6
+
7
+ def pattern
8
+ [
9
+ build_pattern_exec_command(/unzip\s+[^(=|&)]/),
10
+ build_pattern_exec_command(/unzip.*-:/)
11
+ ].join("|")
12
+ end
13
+
14
+ def check(node)
15
+ if Machete.matches?(node, build_pattern_exec_command(/unzip.*-:/))
16
+ issue :high, warning_message, :cwe => [23, 88]
17
+ elsif Machete.matches?(node, build_pattern_exec_command(/unzip\s+[^(=|&)]/))
18
+ issue :medium, warning_message, :cwe => [23, 88]
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def warning_message
25
+ "Unzip option allows '../' in archived file path, dir traversal"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,57 @@
1
+ module Scanny
2
+ module Checks
3
+ class TempFileOpenCheck < Check
4
+ def pattern
5
+ [
6
+ pattern_temp,
7
+ pattern_file_open,
8
+ pattern_mkdir_p
9
+ ].join("|")
10
+ end
11
+
12
+ def check(node)
13
+ issue :medium, warning_message, :cwe => 377
14
+ end
15
+
16
+ private
17
+
18
+ def warning_message
19
+ "Access to the temporary files can lead to" +
20
+ "unauthorized access to data"
21
+ end
22
+
23
+ # File.open("/app/path/tmp_file")
24
+ def pattern_file_open
25
+ <<-EOT
26
+ SendWithArguments<
27
+ arguments = ActualArguments<
28
+ array = [
29
+ StringLiteral<string *= "tmp">
30
+ ]
31
+ >,
32
+ receiver = ConstantAccess<name = :File>,
33
+ name = :open
34
+ >
35
+ EOT
36
+ end
37
+
38
+ # mkdir_p("long/path/tmp/file")
39
+ def pattern_mkdir_p
40
+ <<-EOT
41
+ SendWithArguments<
42
+ arguments = ActualArguments<
43
+ array = [
44
+ StringLiteral<string *= "tmp">
45
+ ]
46
+ >,
47
+ name = :mkdir_p
48
+ >
49
+ EOT
50
+ end
51
+
52
+ def pattern_temp
53
+ 'StringLiteral<string *= /\/tmp\//>'
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,40 @@
1
+ module Scanny
2
+ module Checks
3
+ class UserFindCheck < Check
4
+ def pattern
5
+ pattern_user_find
6
+ end
7
+
8
+ def check(node)
9
+ issue :medium, warning_message, :cwe => [89, 592]
10
+ end
11
+
12
+ private
13
+
14
+ def warning_message
15
+ "Create a user object using the " +
16
+ "parameters can cause security problems"
17
+ end
18
+
19
+ # User.find(params[:input])
20
+ def pattern_user_find
21
+ <<-EOT
22
+ SendWithArguments<
23
+ arguments = ActualArguments<
24
+ array = [
25
+ any*,
26
+ SendWithArguments<
27
+ name = :[],
28
+ receiver = Send<name = :params>
29
+ >,
30
+ any*
31
+ ]
32
+ >,
33
+ name = :find,
34
+ receiver = ConstantAccess<name = :User>
35
+ >
36
+ EOT
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,32 @@
1
+ module Scanny
2
+ module Checks
3
+ class ValidatesCheck < Check
4
+ def pattern
5
+ pattern_validates
6
+ end
7
+
8
+ def check(node)
9
+ issue :info, warning_message
10
+ end
11
+
12
+ def strict?
13
+ true
14
+ end
15
+
16
+ private
17
+
18
+ def warning_message
19
+ "Incorrect validations may allow malicious data transmission"
20
+ end
21
+
22
+ # validates_presence_of :email
23
+ def pattern_validates
24
+ <<-EOT
25
+ SendWithArguments<
26
+ name *= /validates_[\\w]*_of/
27
+ >
28
+ EOT
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,44 @@
1
+ module Scanny
2
+ module Checks
3
+ class VerifyMethodCheck < Check
4
+ def pattern
5
+ pattern_verify
6
+ end
7
+
8
+ def check(node)
9
+ issue :info, warning_message
10
+ end
11
+
12
+ def strict?
13
+ true
14
+ end
15
+
16
+ private
17
+
18
+ def warning_message
19
+ "Incorrect to use the verify method can lead to " +
20
+ "accept additional parameters from request"
21
+ end
22
+
23
+ # verify :method => :get
24
+ def pattern_verify
25
+ <<-EOT
26
+ SendWithArguments<
27
+ arguments = ActualArguments<
28
+ array = [
29
+ HashLiteral<
30
+ array = [
31
+ any{even},
32
+ SymbolLiteral<value = :method>,
33
+ any{odd}
34
+ ]
35
+ >
36
+ ]
37
+ >,
38
+ name = :verify
39
+ >
40
+ EOT
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,70 @@
1
+ module Scanny
2
+ module Checks
3
+ # Check for flash methods that are called with request params or
4
+ # dynamic a string. This allows us to avoid showing dangerous
5
+ # HTML code to users
6
+ class XssFlashCheck < Check
7
+ def pattern
8
+ [
9
+ pattern_params,
10
+ pattern_dynamic_string
11
+ ].join("|")
12
+ end
13
+
14
+ def check(node)
15
+ if Machete.matches?(node, pattern_params)
16
+ issue :high, warning_message, :cwe => 79
17
+ elsif Machete.matches?(node, pattern_dynamic_string)
18
+ issue :medium, warning_message, :cwe => 79
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def warning_message
25
+ "Assigning request parameters into flash can lead to XSS issues."
26
+ end
27
+
28
+ # flash[:warning] = params[:password]
29
+ def pattern_params
30
+ <<-EOT
31
+ ElementAssignment<
32
+ arguments = ActualArguments<
33
+ array = [
34
+ SymbolLiteral<value = :warning>,
35
+ SendWithArguments<
36
+ name = :[],
37
+ receiver = Send<name = :params>
38
+ >
39
+ ]
40
+ >,
41
+ name = :[]=,
42
+ receiver = Send<name = :flash>
43
+ >
44
+ EOT
45
+ end
46
+
47
+ # flash[:warning] = "#{secure_data}"
48
+ def pattern_dynamic_string
49
+ <<-EOT
50
+ ElementAssignment<
51
+ arguments = ActualArguments<
52
+ array = [
53
+ SymbolLiteral<value = :warning>,
54
+ DynamicString<
55
+ array = [
56
+ any*,
57
+ ToString,
58
+ any*
59
+ ]
60
+ >
61
+ ]
62
+ >,
63
+ name = :[]=,
64
+ receiver = Send<name = :flash>
65
+ >
66
+ EOT
67
+ end
68
+ end
69
+ end
70
+ end