brakeman 1.5.1 → 1.5.2

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/bin/brakeman CHANGED
@@ -6,14 +6,6 @@ require 'brakeman'
6
6
  require 'brakeman/options'
7
7
  require 'brakeman/version'
8
8
 
9
- trap("INT") do
10
- $stderr.puts "\nInterrupted - exiting."
11
- if RUBY_VERSION.include? "1.9"
12
- $stderr.puts Thread.current.backtrace
13
- end
14
- exit!
15
- end
16
-
17
9
  #Parse options
18
10
  options, parser = Brakeman::Options.parse! ARGV
19
11
 
@@ -44,6 +36,16 @@ unless options[:app_path]
44
36
  end
45
37
  end
46
38
 
39
+ trap("INT") do
40
+ $stderr.puts "\nInterrupted - exiting."
41
+
42
+ if options[:debug]
43
+ $stderr.puts caller
44
+ end
45
+
46
+ exit!
47
+ end
48
+
47
49
  #Run scan and output a report
48
50
  tracker = Brakeman.run options.merge(:print_report => true, :quiet => options[:quiet])
49
51
 
@@ -78,6 +78,18 @@ class Brakeman::BaseCheck < SexpProcessor
78
78
  exp
79
79
  end
80
80
 
81
+ def process_if exp
82
+ #This is to ignore user input in condition
83
+ current_user_input = @has_user_input
84
+ process exp[1]
85
+ @has_user_input = current_user_input
86
+
87
+ process exp[2] if sexp? exp[2]
88
+ process exp[3] if sexp? exp[3]
89
+
90
+ exp
91
+ end
92
+
81
93
  #Note that params are included in current expression
82
94
  def process_params exp
83
95
  @has_user_input = :params
@@ -42,13 +42,25 @@ class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
42
42
 
43
43
  @matched = false
44
44
 
45
- return if call[3][1].nil?
45
+ #Skip if no arguments(?) or first argument is a hash
46
+ return if call[3][1].nil? or hash? call[3][1]
46
47
 
47
- #Only check first argument for +link_to+, as the second
48
- #will *usually* be a record or escaped.
49
- first_arg = process call[3][1]
48
+ if version_between? "2.0.0", "2.2.99"
49
+ check_argument result, call[3][1]
50
50
 
51
- type, match = has_immediate_user_input? first_arg
51
+ if call[3][2] and not hash? call[3][2]
52
+ check_argument result, call[3][2]
53
+ end
54
+ elsif call[3][2]
55
+ #Only check first argument if there is a second argument
56
+ #in Rails 2.3.x
57
+ check_argument result, call[3][1]
58
+ end
59
+ end
60
+
61
+ def check_argument result, exp
62
+ arg = process exp
63
+ type, match = has_immediate_user_input? arg
52
64
 
53
65
  if type
54
66
  case type
@@ -65,7 +77,7 @@ class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
65
77
  :warning_type => "Cross Site Scripting",
66
78
  :message => message,
67
79
  :confidence => CONFIDENCE[:high]
68
- elsif not tracker.options[:ignore_model_output] and match = has_immediate_model?(first_arg)
80
+ elsif not tracker.options[:ignore_model_output] and match = has_immediate_model?(arg)
69
81
  method = match[2]
70
82
 
71
83
  unless IGNORE_MODEL_METHODS.include? method
@@ -29,30 +29,44 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
29
29
  def check_for_dynamic_path result
30
30
  view = result[:call][2]
31
31
 
32
- if sexp? view and view.node_type != :str and view.node_type != :lit and not duplicate? result
33
-
32
+ if sexp? view and not duplicate? result
34
33
  add_result result
35
34
 
36
- if include_user_input? view
35
+ type, match = has_immediate_user_input? view
36
+
37
+ if type
37
38
  confidence = CONFIDENCE[:high]
39
+ elsif type = include_user_input?(view)
40
+ if node_type? view, :string_interp, :dstr
41
+ confidence = CONFIDENCE[:med]
42
+ else
43
+ confidence = CONFIDENCE[:low]
44
+ end
38
45
  else
39
- confidence = CONFIDENCE[:low]
46
+ return
40
47
  end
41
48
 
42
- warning = { :warning_type => "Dynamic Render Path",
43
- :message => "Render path is dynamic",
44
- :line => result[:call].line,
45
- :code => result[:call],
46
- :confidence => confidence }
49
+ message = "Render path contains "
47
50
 
48
- if result[:location][0] == :template
49
- warning[:template] = result[:location][1]
51
+ case type
52
+ when :params
53
+ message << "parameter value"
54
+ when :cookies
55
+ message << "cookie value"
56
+ when :request
57
+ message << "request value"
58
+ when :model
59
+ #Skip models
60
+ return
50
61
  else
51
- warning[:class] = result[:location][1]
52
- warning[:method] = result[:location][2]
62
+ message << "user input value"
53
63
  end
54
64
 
55
- warn warning
65
+
66
+ warn :result => result,
67
+ :warning_type => "Dynamic Render Path",
68
+ :message => message,
69
+ :confidence => confidence
56
70
  end
57
71
  end
58
72
  end
@@ -201,7 +201,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
201
201
  true
202
202
  elsif call? target
203
203
  check_call target
204
- elsif target == nil and tracker.options[:rails3] and method.to_s.match /^first|last|all|where|order|group|having$/
204
+ elsif target == nil and tracker.options[:rails3] and method.to_s.match(/^first|last|all|where|order|group|having$/)
205
205
  check_arguments args
206
206
  else
207
207
  false
@@ -91,7 +91,7 @@ module Brakeman::Options
91
91
 
92
92
  opts.on "--skip-files file1,file2,etc", Array, "Skip processing of these files" do |files|
93
93
  options[:skip_files] ||= Set.new
94
- options[:skip_files].merge files.map {|f| f.to_sym }
94
+ options[:skip_files].merge files
95
95
  end
96
96
 
97
97
  opts.on "--skip-libs", "Skip processing lib directory" do
@@ -12,16 +12,22 @@ class Brakeman::ErubisTemplateProcessor < Brakeman::TemplateProcessor
12
12
  method = exp[2]
13
13
 
14
14
  #_buf is the default output variable for Erubis
15
- if target and (target[1] == :_buf or target[1] == :output_buffer)
15
+ if target and (target[1] == :_buf or target[1] == :@output_buffer)
16
16
  if method == :<< or method == :safe_concat
17
17
  args = exp[3][1] = process(exp[3][1])
18
18
 
19
- if args.node_type == :call and args[2] == :to_s #just calling to_s on inner code
19
+ #We want the actual content
20
+ if args.node_type == :call and (args[2] == :to_s or args[2] == :html_safe!)
20
21
  args = args[1]
21
22
  end
22
23
 
23
24
  if args.node_type == :str #ignore plain strings
24
25
  ignore
26
+ elsif target[1] == :@output_buffer
27
+ s = Sexp.new :escaped_output, args
28
+ s.line(exp.line)
29
+ @current_template[:outputs] << s
30
+ s
25
31
  else
26
32
  s = Sexp.new :output, args
27
33
  s.line(exp.line)
@@ -31,7 +37,7 @@ class Brakeman::ErubisTemplateProcessor < Brakeman::TemplateProcessor
31
37
  elsif method == :to_s
32
38
  ignore
33
39
  else
34
- abort "Unrecognized action on _buf: #{method}"
40
+ abort "Unrecognized action on buffer: #{method}"
35
41
  end
36
42
  elsif target == nil and method == :render
37
43
  exp[3] = process exp[3]
@@ -74,7 +74,7 @@ class Brakeman::Rescanner < Brakeman::Scanner
74
74
  when :model
75
75
  rescan_model path
76
76
  when :lib
77
- process_library path
77
+ process_lib path
78
78
  when :config
79
79
  process_config
80
80
  when :initializer
@@ -1,7 +1,12 @@
1
1
  require 'rubygems'
2
2
  begin
3
- #Load our own version of ruby_parser :'(
4
- require 'ruby_parser/ruby_parser.rb'
3
+ if RUBY_VERSION =~ /^1\.9/
4
+ #Load our own version of ruby_parser :'(
5
+ require 'ruby_parser/ruby_parser.rb'
6
+ else
7
+ require 'ruby_parser'
8
+ require 'ruby_parser/bm_sexp.rb'
9
+ end
5
10
 
6
11
  require 'haml'
7
12
  require 'sass'
@@ -47,7 +52,7 @@ class Brakeman::Scanner
47
52
  if RUBY_1_9
48
53
  @ruby_parser = ::Ruby19Parser
49
54
  else
50
- @ruby_parser = ::Ruby18Parser
55
+ @ruby_parser = ::RubyParser
51
56
  end
52
57
  end
53
58
 
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "1.5.1"
2
+ Version = "1.5.2"
3
3
  end
@@ -0,0 +1,112 @@
1
+ #Sexp changes from ruby_parser
2
+ #and some changes for caching hash value and tracking 'original' line number
3
+ #of a Sexp.
4
+ class Sexp
5
+ attr_reader :paren
6
+
7
+ def paren
8
+ @paren ||= false
9
+ end
10
+
11
+ def value
12
+ raise "multi item sexp" if size > 2
13
+ last
14
+ end
15
+
16
+ def to_sym
17
+ self.value.to_sym
18
+ end
19
+
20
+ alias :node_type :sexp_type
21
+ alias :values :sexp_body # TODO: retire
22
+
23
+ alias :old_init :initialize
24
+ alias :old_push :<<
25
+ alias :old_line :line
26
+ alias :old_line_set :line=
27
+ alias :old_file_set :file=
28
+ alias :old_comments_set :comments=
29
+ alias :old_compact :compact
30
+ alias :old_fara :find_and_replace_all
31
+ alias :old_find_node :find_node
32
+
33
+ def initialize *args
34
+ old_init(*args)
35
+ @original_line = nil
36
+ @my_hash_value = nil
37
+ end
38
+
39
+ def original_line line = nil
40
+ if line
41
+ @my_hash_value = nil
42
+ @original_line = line
43
+ else
44
+ @original_line
45
+ end
46
+ end
47
+
48
+ def hash
49
+ #There still seems to be some instances in which the hash of the
50
+ #Sexp changes, but I have not found what method call is doing it.
51
+ #Of course, Sexp is subclasses from Array, so who knows what might
52
+ #be going on.
53
+ @my_hash_value ||= super
54
+ end
55
+
56
+ def line *args
57
+ @my_hash_value = nil
58
+ old_line(*args)
59
+ end
60
+
61
+ def line= *args
62
+ @my_hash_value = nil
63
+ old_line_set(*args)
64
+ end
65
+
66
+ def file= *args
67
+ @my_hash_value = nil
68
+ old_file_set(*args)
69
+ end
70
+
71
+ def compact
72
+ @my_hash_value = nil
73
+ old_compact
74
+ end
75
+
76
+ def find_and_replace_all *args
77
+ @my_hash_value = nil
78
+ old_fara(*args)
79
+ end
80
+
81
+ def find_node *args
82
+ @my_hash_value = nil
83
+ old_find_node(*args)
84
+ end
85
+
86
+ def paren= arg
87
+ @my_hash_value = nil
88
+ @paren = arg
89
+ end
90
+
91
+ def comments= *args
92
+ @my_hash_value = nil
93
+ old_comments_set(*args)
94
+ end
95
+ end
96
+
97
+ #Invalidate hash cache if the Sexp changes
98
+ [:[]=, :clear, :collect!, :compact!, :concat, :delete, :delete_at,
99
+ :delete_if, :drop, :drop_while, :fill, :flatten!, :replace, :insert,
100
+ :keep_if, :map!, :pop, :push, :reject!, :replace, :reverse!, :rotate!,
101
+ :select!, :shift, :shuffle!, :slice!, :sort!, :sort_by!, :transpose,
102
+ :uniq!, :unshift].each do |method|
103
+
104
+ Sexp.class_eval <<-RUBY
105
+ def #{method} *args
106
+ @my_hash_value = nil
107
+ super
108
+ end
109
+ RUBY
110
+ end
111
+
112
+
@@ -1051,113 +1051,7 @@ class Symbol
1051
1051
  end
1052
1052
  end
1053
1053
 
1054
- class Sexp
1055
- attr_reader :paren
1056
-
1057
- def paren
1058
- @paren ||= false
1059
- end
1060
-
1061
- def value
1062
- raise "multi item sexp" if size > 2
1063
- last
1064
- end
1065
-
1066
- def to_sym
1067
- self.value.to_sym
1068
- end
1069
-
1070
- alias :node_type :sexp_type
1071
- alias :values :sexp_body # TODO: retire
1072
-
1073
- alias :old_init :initialize
1074
- alias :old_push :<<
1075
- alias :old_line :line
1076
- alias :old_line_set :line=
1077
- alias :old_file_set :file=
1078
- alias :old_comments_set :comments=
1079
- alias :old_compact :compact
1080
- alias :old_fara :find_and_replace_all
1081
- alias :old_find_node :find_node
1082
-
1083
- def initialize *args
1084
- old_init *args
1085
- @original_line = nil
1086
- @my_hash_value = nil
1087
- end
1088
-
1089
- def original_line line = nil
1090
- if line
1091
- @my_hash_value = nil
1092
- @original_line = line
1093
- else
1094
- @original_line
1095
- end
1096
- end
1097
-
1098
- def hash
1099
- #There still seems to be some instances in which the hash of the
1100
- #Sexp changes, but I have not found what method call is doing it.
1101
- #Of course, Sexp is subclasses from Array, so who knows what might
1102
- #be going on.
1103
- @my_hash_value ||= super
1104
- end
1105
-
1106
- def line *args
1107
- @my_hash_value = nil
1108
- old_line *args
1109
- end
1110
-
1111
- def line= *args
1112
- @my_hash_value = nil
1113
- old_line_set *args
1114
- end
1115
-
1116
- def file= *args
1117
- @my_hash_value = nil
1118
- old_file_set *args
1119
- end
1120
-
1121
- def compact
1122
- @my_hash_value = nil
1123
- old_compact
1124
- end
1125
-
1126
- def find_and_replace_all *args
1127
- @my_hash_value = nil
1128
- old_fara *args
1129
- end
1130
-
1131
- def find_node *args
1132
- @my_hash_value = nil
1133
- old_find_node *args
1134
- end
1135
-
1136
- def paren= arg
1137
- @my_hash_value = nil
1138
- @paren = arg
1139
- end
1140
-
1141
- def comments= *args
1142
- @my_hash_value = nil
1143
- old_comments_set *args
1144
- end
1145
- end
1146
-
1147
- #Invalidate hash cache if the Sexp changes
1148
- [:[]=, :clear, :collect!, :compact!, :concat, :delete, :delete_at,
1149
- :delete_if, :drop, :drop_while, :fill, :flatten!, :replace, :insert,
1150
- :keep_if, :map!, :pop, :push, :reject!, :replace, :reverse!, :rotate!,
1151
- :select!, :shift, :shuffle!, :slice!, :sort!, :sort_by!, :transpose,
1152
- :uniq!, :unshift].each do |method|
1153
-
1154
- Sexp.class_eval <<-RUBY
1155
- def #{method} *args
1156
- @my_hash_value = nil
1157
- super
1158
- end
1159
- RUBY
1160
- end
1054
+ require 'bm_sexp'
1161
1055
 
1162
1056
  # END HACK
1163
1057
  ############################################################
metadata CHANGED
@@ -1,107 +1,141 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: brakeman
3
- version: !ruby/object:Gem::Version
4
- version: 1.5.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 7
5
5
  prerelease:
6
+ segments:
7
+ - 1
8
+ - 5
9
+ - 2
10
+ version: 1.5.2
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Justin Collins
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-03-06 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-03-22 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: activesupport
16
- requirement: &72282300 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
17
24
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
22
32
  type: :runtime
23
- prerelease: false
24
- version_requirements: *72282300
25
- - !ruby/object:Gem::Dependency
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
26
35
  name: i18n
27
- requirement: &72282080 !ruby/object:Gem::Requirement
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
28
38
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
33
46
  type: :runtime
34
- prerelease: false
35
- version_requirements: *72282080
36
- - !ruby/object:Gem::Dependency
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
37
49
  name: ruby2ruby
38
- requirement: &72281550 !ruby/object:Gem::Requirement
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
39
52
  none: false
40
- requirements:
53
+ requirements:
41
54
  - - ~>
42
- - !ruby/object:Gem::Version
43
- version: '1.2'
55
+ - !ruby/object:Gem::Version
56
+ hash: 11
57
+ segments:
58
+ - 1
59
+ - 2
60
+ version: "1.2"
44
61
  type: :runtime
45
- prerelease: false
46
- version_requirements: *72281550
47
- - !ruby/object:Gem::Dependency
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
48
64
  name: ruport
49
- requirement: &72280450 !ruby/object:Gem::Requirement
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
50
67
  none: false
51
- requirements:
68
+ requirements:
52
69
  - - ~>
53
- - !ruby/object:Gem::Version
54
- version: '1.6'
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 1
74
+ - 6
75
+ version: "1.6"
55
76
  type: :runtime
56
- prerelease: false
57
- version_requirements: *72280450
58
- - !ruby/object:Gem::Dependency
77
+ version_requirements: *id004
78
+ - !ruby/object:Gem::Dependency
59
79
  name: erubis
60
- requirement: &72280190 !ruby/object:Gem::Requirement
80
+ prerelease: false
81
+ requirement: &id005 !ruby/object:Gem::Requirement
61
82
  none: false
62
- requirements:
83
+ requirements:
63
84
  - - ~>
64
- - !ruby/object:Gem::Version
65
- version: '2.6'
85
+ - !ruby/object:Gem::Version
86
+ hash: 15
87
+ segments:
88
+ - 2
89
+ - 6
90
+ version: "2.6"
66
91
  type: :runtime
67
- prerelease: false
68
- version_requirements: *72280190
69
- - !ruby/object:Gem::Dependency
92
+ version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
70
94
  name: haml
71
- requirement: &72279750 !ruby/object:Gem::Requirement
95
+ prerelease: false
96
+ requirement: &id006 !ruby/object:Gem::Requirement
72
97
  none: false
73
- requirements:
98
+ requirements:
74
99
  - - ~>
75
- - !ruby/object:Gem::Version
76
- version: '3.0'
100
+ - !ruby/object:Gem::Version
101
+ hash: 7
102
+ segments:
103
+ - 3
104
+ - 0
105
+ version: "3.0"
77
106
  type: :runtime
78
- prerelease: false
79
- version_requirements: *72279750
80
- - !ruby/object:Gem::Dependency
107
+ version_requirements: *id006
108
+ - !ruby/object:Gem::Dependency
81
109
  name: sass
82
- requirement: &72279400 !ruby/object:Gem::Requirement
110
+ prerelease: false
111
+ requirement: &id007 !ruby/object:Gem::Requirement
83
112
  none: false
84
- requirements:
113
+ requirements:
85
114
  - - ~>
86
- - !ruby/object:Gem::Version
87
- version: '3.0'
115
+ - !ruby/object:Gem::Version
116
+ hash: 7
117
+ segments:
118
+ - 3
119
+ - 0
120
+ version: "3.0"
88
121
  type: :runtime
89
- prerelease: false
90
- version_requirements: *72279400
91
- description: Brakeman detects security vulnerabilities in Ruby on Rails applications
92
- via static analysis.
122
+ version_requirements: *id007
123
+ description: Brakeman detects security vulnerabilities in Ruby on Rails applications via static analysis.
93
124
  email:
94
- executables:
125
+ executables:
95
126
  - brakeman
96
127
  extensions: []
128
+
97
129
  extra_rdoc_files: []
98
- files:
130
+
131
+ files:
99
132
  - bin/brakeman
100
133
  - WARNING_TYPES
101
134
  - FEATURES
102
135
  - README.md
103
136
  - lib/ruby_parser/ruby18_parser.rb
104
137
  - lib/ruby_parser/ruby_parser_extras.rb
138
+ - lib/ruby_parser/bm_sexp.rb
105
139
  - lib/ruby_parser/ruby_lexer.rb
106
140
  - lib/ruby_parser/ruby_parser.rb
107
141
  - lib/ruby_parser/ruby19_parser.rb
@@ -175,26 +209,36 @@ files:
175
209
  - lib/brakeman/format/style.css
176
210
  homepage: http://brakemanscanner.org
177
211
  licenses: []
212
+
178
213
  post_install_message:
179
214
  rdoc_options: []
180
- require_paths:
215
+
216
+ require_paths:
181
217
  - lib
182
- required_ruby_version: !ruby/object:Gem::Requirement
218
+ required_ruby_version: !ruby/object:Gem::Requirement
183
219
  none: false
184
- requirements:
185
- - - ! '>='
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- required_rubygems_version: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ hash: 3
224
+ segments:
225
+ - 0
226
+ version: "0"
227
+ required_rubygems_version: !ruby/object:Gem::Requirement
189
228
  none: false
190
- requirements:
191
- - - ! '>='
192
- - !ruby/object:Gem::Version
193
- version: '0'
229
+ requirements:
230
+ - - ">="
231
+ - !ruby/object:Gem::Version
232
+ hash: 3
233
+ segments:
234
+ - 0
235
+ version: "0"
194
236
  requirements: []
237
+
195
238
  rubyforge_project:
196
239
  rubygems_version: 1.8.15
197
240
  signing_key:
198
241
  specification_version: 3
199
242
  summary: Security vulnerability scanner for Ruby on Rails.
200
243
  test_files: []
244
+