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,39 @@
1
+ module Scanny
2
+ module Checks
3
+ class InputFilteringCheck < Check
4
+ def pattern
5
+ [
6
+ pattern_terminal_escape_sequences,
7
+ pattern_params
8
+ ].join("|")
9
+ end
10
+
11
+ def check(node)
12
+ issue :low, warning_message, :cwe => 20
13
+ end
14
+
15
+ private
16
+
17
+ def warning_message
18
+ "Possible injection vulnerabilities"
19
+ end
20
+
21
+ # params[:input]
22
+ def pattern_params
23
+ <<-EOT
24
+ SendWithArguments<
25
+ name = :[],
26
+ receiver = Send<name = :params>
27
+ >
28
+ EOT
29
+ end
30
+
31
+ # system("\033]30;command\007")
32
+ def pattern_terminal_escape_sequences
33
+ <<-EOT
34
+ StringLiteral<string *= /\\033\]30;.*\\007/>
35
+ EOT
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ module Scanny
2
+ module Checks
3
+ # Checks for places where ENV["RAILS_ENV"] is set.
4
+ class SetRailsEnvCheck < Check
5
+ # ENV["RAILS_ENV"] = "test"
6
+ def pattern
7
+ <<-EOT
8
+ ElementAssignment<
9
+ receiver = ConstantAccess<name = :ENV>,
10
+ arguments = ActualArguments<
11
+ array = [StringLiteral<string = "RAILS_ENV">, any]
12
+ >
13
+ >
14
+ EOT
15
+ end
16
+
17
+ def check(node)
18
+ issue :info,
19
+ "Setting ENV[\"RAILS_ENV\"] can indicate insecure configuration.",
20
+ :cwe => 209
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ module Scanny
2
+ module Checks
3
+ # Checks for places where :secret hash key is set.
4
+ class SetSecretCheck < Check
5
+ # :secret
6
+ def pattern
7
+ <<-EOT
8
+ HashLiteral<
9
+ array = [any{even}, SymbolLiteral<value = :secret>, any{odd}]
10
+ >
11
+ EOT
12
+ end
13
+
14
+ def check(node)
15
+ issue :info,
16
+ "Setting :secret can indicate using hard-coded cryptographic key.",
17
+ :cwe => 321
18
+ end
19
+
20
+ def strict?
21
+ true
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ module Scanny
2
+ module Checks
3
+ # Checks for places where :session_key hash key is set.
4
+ class SetSessionKeyCheck < Check
5
+ # :session_key
6
+ def pattern
7
+ <<-EOT
8
+ HashLiteral<
9
+ array = [any{even}, SymbolLiteral<value = :session_key>, any{odd}]
10
+ >
11
+ EOT
12
+ end
13
+
14
+ def check(node)
15
+ issue :info, "Setting :session_key."
16
+ end
17
+
18
+ def strict?
19
+ true
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ module Scanny
2
+ module Checks
3
+ module InsecureMethod
4
+ class EvalMethodCheck < Check
5
+ def pattern
6
+ pattern_eval_call
7
+ end
8
+
9
+ def check(node)
10
+ issue :high, warning_message, :cwe => 95
11
+ end
12
+
13
+ private
14
+
15
+ def warning_message
16
+ "Execute eval method can lead the ruby interpreter to run dangerous code"
17
+ end
18
+
19
+ # eval("ruby_code")
20
+ def pattern_eval_call
21
+ "SendWithArguments<name = :eval>"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ module Scanny
2
+ module Checks
3
+ module InsecureMethod
4
+ class MarshalCheck < Check
5
+ def pattern
6
+ pattern_load_call
7
+ end
8
+
9
+ def check(node)
10
+ issue :high, warning_message, :cwe => 502
11
+ end
12
+
13
+ private
14
+
15
+ def warning_message
16
+ "Execute deserialize method can load to memory dangerous object"
17
+ end
18
+
19
+ # Marshal.load(object)
20
+ def pattern_load_call
21
+ <<-EOT
22
+ SendWithArguments<
23
+ name = :load | :restore,
24
+ receiver = ConstantAccess<
25
+ name = :Marshal
26
+ >
27
+ >
28
+ EOT
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ module Scanny
2
+ module Checks
3
+ module InsecureMethod
4
+ class SystemMethodCheck < Check
5
+ def pattern
6
+ [
7
+ pattern_system_calls,
8
+ pattern_execute_string,
9
+ pattern_popen
10
+ ].join("|")
11
+ end
12
+
13
+ def check(node)
14
+ issue :high, warning_message, :cwe => [88, 78]
15
+ end
16
+
17
+ private
18
+
19
+ def warning_message
20
+ "Execute system commands can lead the system to run dangerous code"
21
+ end
22
+
23
+ # system("rm -rf /")
24
+ def pattern_system_calls
25
+ <<-EOT
26
+ SendWithArguments
27
+ <
28
+ name = :system |
29
+ :spawn |
30
+ :exec
31
+ >
32
+ EOT
33
+ end
34
+
35
+ def pattern_popen
36
+ "SendWithArguments<name ^= :popen>"
37
+ end
38
+
39
+ # `system_command`
40
+ def pattern_execute_string
41
+ "ExecuteString"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,48 @@
1
+ module Scanny
2
+ module Checks
3
+ class MassAssignmentCheck < Check
4
+ def pattern
5
+ pattern_create_object_from_params
6
+ end
7
+
8
+ def check(node)
9
+ issue :high, warning_message, :cwe => 642
10
+ end
11
+
12
+ private
13
+
14
+ def warning_message
15
+ "Create objects without defense against mass assignment" +
16
+ "can cause dangerous errors in the database"
17
+ end
18
+
19
+ # User.new(params[:user])
20
+ def pattern_create_object_from_params
21
+ <<-EOT
22
+ SendWithArguments<
23
+ arguments = ActualArguments<
24
+ array = [
25
+ SendWithArguments<
26
+ name = :[],
27
+ receiver = Send<name = :params>
28
+ >
29
+ |
30
+ HashLiteral<
31
+ array = [
32
+ any{odd},
33
+ SendWithArguments<
34
+ name = :[],
35
+ receiver = Send<name = :params>
36
+ >,
37
+ any{even}
38
+ ]
39
+ >
40
+ ]
41
+ >,
42
+ name = :new | :create | :update_attributes
43
+ >
44
+ EOT
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,54 @@
1
+ module Scanny
2
+ module Checks
3
+ # Checks for indication that a low-entropy random number generator is used.
4
+ class RandomNumbersCheck < Check
5
+ def pattern
6
+ [
7
+ pattern_rand,
8
+ pattern_seed,
9
+ pattern_urandom
10
+ ].join("|")
11
+ end
12
+
13
+ def check(node)
14
+ issue :medium, warning_message, :cwe => 331
15
+ end
16
+
17
+ private
18
+
19
+ def warning_message
20
+ "This action indicates using low-entropy random number generator"
21
+ end
22
+
23
+ # Kernel.srand
24
+ # Kernel.rand
25
+ def pattern_rand
26
+ <<-EOT
27
+ Send<
28
+ receiver = Self | ConstantAccess<name = :Kernel>,
29
+ name = :rand | :srand
30
+ >
31
+ |
32
+ SendWithArguments<
33
+ receiver = Self | ConstantAccess<name = :Kernel>,
34
+ name = :rand | :srand
35
+ >
36
+ EOT
37
+ end
38
+
39
+ # seed()
40
+ def pattern_seed
41
+ <<-EOT
42
+ Send<name = :seed>
43
+ |
44
+ SendWithArguments<name = :seed>
45
+ EOT
46
+ end
47
+
48
+ # File.open("/dev/urandom", "r").read(100)
49
+ def pattern_urandom
50
+ "StringLiteral<string *= 'urandom'>"
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,48 @@
1
+ module Scanny
2
+ module Checks
3
+ class RedirectWithParamsCheck < Check
4
+ def pattern
5
+ pattern_redirect
6
+ end
7
+
8
+ def check(node)
9
+ issue :medium, warning_message, :cwe => [79, 113, 601, 698]
10
+ end
11
+
12
+ private
13
+
14
+ def warning_message
15
+ "Use of external parameters in redirect_to method" +
16
+ "can lead to unauthorized redirects"
17
+ end
18
+
19
+ # redirect_to params[:input]
20
+ def pattern_redirect
21
+ <<-EOT
22
+ SendWithArguments<
23
+ arguments = ActualArguments<
24
+ array = [
25
+ HashLiteral<
26
+ array = [
27
+ any{odd},
28
+ SendWithArguments<
29
+ name = :[],
30
+ receiver = Send<name = :params>
31
+ >,
32
+ any{even}
33
+ ]
34
+ >
35
+ |
36
+ SendWithArguments<
37
+ name = :[],
38
+ receiver = Send<name = :params>
39
+ >
40
+ ]
41
+ >,
42
+ name = :redirect_to
43
+ >
44
+ EOT
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,23 @@
1
+ module Scanny
2
+ module Checks
3
+ # Checks for possible improper regular expression usage.
4
+ class RegexpCheck < Check
5
+ def pattern
6
+ <<-EOT
7
+ RegexLiteral<source ^= "^">
8
+ |
9
+ RegexLiteral<source $= "$">
10
+ |
11
+ DynamicRegex<string ^= "^">
12
+ |
13
+ DynamicRegex<array = [any*, StringLiteral<string $= "$">]>
14
+ EOT
15
+ end
16
+
17
+ def check(node)
18
+ issue :low, "Possible improper regular expression usage.",
19
+ :cwe => [185, 625, 791]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ module Scanny
2
+ module Checks
3
+ class ResetSessionCheck < Check
4
+ def pattern
5
+ pattern_reset_session
6
+ end
7
+
8
+ def check(node)
9
+ issue :info, warning_message, :cwe => 384
10
+ end
11
+
12
+ private
13
+
14
+ def warning_message
15
+ "Improper resetting the session may lead to security problems"
16
+ end
17
+
18
+ # reset_session()
19
+ def pattern_reset_session
20
+ "Send<name = :reset_session>"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,49 @@
1
+ module Scanny
2
+ module Checks
3
+ module Session
4
+ class AccessToSessionCheck < Check
5
+ def pattern
6
+ [
7
+ pattern_session_access,
8
+ pattern_session_assignment
9
+ ].join("|")
10
+ end
11
+
12
+ def check(node)
13
+ issue :info, warning_message
14
+ end
15
+
16
+ def strict?
17
+ true
18
+ end
19
+
20
+ private
21
+
22
+ def warning_message
23
+ "Referring to a session in the wrong way" +
24
+ "can lead to errors that reduce security level"
25
+ end
26
+
27
+ # session[:password]
28
+ def pattern_session_access
29
+ <<-EOT
30
+ SendWithArguments<
31
+ name = :[],
32
+ receiver = Send<name = :session | :cookie>
33
+ >
34
+ EOT
35
+ end
36
+
37
+ # session[:admin] = true
38
+ def pattern_session_assignment
39
+ <<-EOT
40
+ ElementAssignment<
41
+ name = :[]=,
42
+ receiver = Send<name = :session | :cookie>
43
+ >
44
+ EOT
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end