Module: Brakeman::Util
- Included in:
- AliasProcessor, BaseCheck, BaseProcessor, BasicProcessor, Collection, Config, Constant, Constants, FindReturnValue, MethodInfo, OutputProcessor, Processor, Report::Base, RescanReport, Rescanner, TemplateParser
- Defined in:
- lib/brakeman/util.rb
Overview
This is a mixin containing utility methods.
Constant Summary collapse
- QUERY_PARAMETERS =
Sexp.new(:call, Sexp.new(:call, nil, :request), :query_parameters)
- PATH_PARAMETERS =
Sexp.new(:call, Sexp.new(:call, nil, :request), :path_parameters)
- REQUEST_REQUEST_PARAMETERS =
Sexp.new(:call, Sexp.new(:call, nil, :request), :request_parameters)
- REQUEST_PARAMETERS =
Sexp.new(:call, Sexp.new(:call, nil, :request), :parameters)
- REQUEST_PARAMS =
Sexp.new(:call, Sexp.new(:call, nil, :request), :params)
- REQUEST_ENV =
Sexp.new(:call, Sexp.new(:call, nil, :request), :env)
- PARAMETERS =
Sexp.new(:call, nil, :params)
- COOKIES =
Sexp.new(:call, nil, :cookies)
- REQUEST_COOKIES =
s(:call, s(:call, nil, :request), :cookies)
- SESSION =
Sexp.new(:call, nil, :session)
- ALL_PARAMETERS =
Set[PARAMETERS, QUERY_PARAMETERS, PATH_PARAMETERS, REQUEST_REQUEST_PARAMETERS, REQUEST_PARAMETERS, REQUEST_PARAMS]
- ALL_COOKIES =
Set[COOKIES, REQUEST_COOKIES]
- SAFE_LITERAL =
s(:lit, :BRAKEMAN_SAFE_LITERAL)
- PARAMS_SEXP =
These are never modified
Sexp.new(:params)
- SESSION_SEXP =
Sexp.new(:session)
- COOKIES_SEXP =
Sexp.new(:cookies)
- SIMPLE_LITERALS =
[:lit, :false, :str, :true]
- LITERALS =
[*SIMPLE_LITERALS, :array, :hash]
- DIR_CONST =
s(:const, :Dir)
Instance Method Summary collapse
- #all_literals?(exp, expected_type = :array) ⇒ Boolean
-
#array?(exp) ⇒ Boolean
Check if exp represents an array: s(:array, […]).
-
#block?(exp) ⇒ Boolean
Check if exp represents a block of code.
-
#call?(exp) ⇒ Boolean
Check if exp represents a method call: s(:call, …).
-
#camelize(lower_case_and_underscored_word) ⇒ Object
Convert a string from “something_like_this” to “SomethingLikeThis”.
-
#class_name(exp) ⇒ Object
Returns a class name as a Symbol.
- #constant?(exp) ⇒ Boolean
-
#contains_class?(exp) ⇒ Boolean
Returns true if the given exp contains a :class node.
- #cookies?(exp) ⇒ Boolean
-
#dir_glob?(exp) ⇒ Boolean
Dir.glob(…).whatever.
-
#false?(exp) ⇒ Boolean
Check if exp represents a :false or :nil node.
-
#hash?(exp) ⇒ Boolean
Check if exp represents a hash: s(:hash, …) This also includes pseudo hashes params, session, and cookies.
-
#hash_access(hash, key) ⇒ Object
Get value from hash using key.
-
#hash_insert(hash, key, value) ⇒ Object
Insert value into Hash Sexp.
-
#hash_iterate(hash) ⇒ Object
Takes an Sexp like (:hash, (:lit, :key), (:str, “value”)) and yields the key and value pairs to the given block.
- #hash_values(hash) ⇒ Object
-
#integer?(exp) ⇒ Boolean
Check if exp represents an Integer: s(:lit, …).
- #kwsplat?(exp) ⇒ Boolean
- #literal?(exp) ⇒ Boolean
- #make_call(target, method, *args) ⇒ Object
-
#node_type?(exp, *types) ⇒ Boolean
Check if exp is a Sexp and the node type matches one of the given types.
-
#number?(exp) ⇒ Boolean
Check if exp represents a number: s(:lit, …).
-
#params?(exp) ⇒ Boolean
Check if exp is a params hash.
-
#pluralize(word) ⇒ Object
stupid simple, used to delegate to ActiveSupport.
- #rails_version ⇒ Object
- #recurse_check?(exp, &check) ⇒ Boolean
-
#regexp?(exp) ⇒ Boolean
Check if exp represents a Regexp: s(:lit, /…/).
- #remove_kwsplat(exp) ⇒ Object
-
#request_headers?(exp) ⇒ Boolean
Only return true when accessing request headers via request.env.
-
#request_value?(exp) ⇒ Boolean
Check if exp is params, cookies, or request_headers.
-
#result?(exp) ⇒ Boolean
Check if exp represents a result: s(:result, …).
- #safe_literal(line = nil) ⇒ Object
- #safe_literal?(exp) ⇒ Boolean
- #safe_literal_target?(exp) ⇒ Boolean
-
#set_env_defaults ⇒ Object
Adds params, session, and cookies to environment so they can be replaced by their respective Sexps.
-
#sexp?(exp) ⇒ Boolean
Check if exp is a Sexp.
- #simple_literal?(exp) ⇒ Boolean
-
#string?(exp) ⇒ Boolean
Check if exp represents a String: s(:str, “…”).
- #string_interp?(exp) ⇒ Boolean
-
#symbol?(exp) ⇒ Boolean
Check if exp represents a Symbol: s(:lit, :…).
-
#template_path_to_name(path) ⇒ Object
Convert path/filename to view name.
-
#true?(exp) ⇒ Boolean
Check if exp represents a :true, :lit, or :string node.
-
#underscore(camel_cased_word) ⇒ Object
Convert a string from “Something::LikeThis” to “something/like_this”.
Instance Method Details
#all_literals?(exp, expected_type = :array) ⇒ Boolean
328 329 330 331 332 |
# File 'lib/brakeman/util.rb', line 328 def all_literals? exp, expected_type = :array node_type? exp, expected_type and exp.length > 1 and exp.all? { |e| e.is_a? Symbol or node_type? e, :lit, :str } end |
#array?(exp) ⇒ Boolean
Check if exp represents an array: s(:array, […])
180 181 182 |
# File 'lib/brakeman/util.rb', line 180 def array? exp exp.is_a? Sexp and exp.node_type == :array end |
#block?(exp) ⇒ Boolean
Check if exp represents a block of code
238 239 240 241 |
# File 'lib/brakeman/util.rb', line 238 def block? exp exp.is_a? Sexp and (exp.node_type == :block or exp.node_type == :rlist) end |
#call?(exp) ⇒ Boolean
Check if exp represents a method call: s(:call, …)
199 200 201 202 |
# File 'lib/brakeman/util.rb', line 199 def call? exp exp.is_a? Sexp and (exp.node_type == :call or exp.node_type == :safe_call) end |
#camelize(lower_case_and_underscored_word) ⇒ Object
Convert a string from “something_like_this” to “SomethingLikeThis”
Taken from ActiveSupport.
36 37 38 |
# File 'lib/brakeman/util.rb', line 36 def camelize lower_case_and_underscored_word lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } end |
#class_name(exp) ⇒ Object
Returns a class name as a Symbol. If class name cannot be determined, returns exp.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/brakeman/util.rb', line 62 def class_name exp case exp when Sexp case exp.node_type when :const exp.value when :lvar exp.value.to_sym when :colon2 "#{class_name(exp.lhs)}::#{exp.rhs}".to_sym when :colon3 "::#{exp.value}".to_sym when :self @current_class || @current_module || nil else exp end when Symbol exp when nil nil else exp end end |
#constant?(exp) ⇒ Boolean
295 296 297 |
# File 'lib/brakeman/util.rb', line 295 def constant? exp node_type? exp, :const, :colon2, :colon3 end |
#contains_class?(exp) ⇒ Boolean
Returns true if the given exp contains a :class node.
Useful for checking if a module is just a module or if it is a namespace.
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/brakeman/util.rb', line 347 def contains_class? exp todo = [exp] until todo.empty? current = todo.shift if node_type? current, :class return true elsif sexp? current todo = current.sexp_body.concat todo end end false end |
#cookies?(exp) ⇒ Boolean
248 249 250 |
# File 'lib/brakeman/util.rb', line 248 def exp recurse_check?(exp) { |child| child.node_type == :cookies or ALL_COOKIES.include? child } end |
#dir_glob?(exp) ⇒ Boolean
Dir.glob(…).whatever
337 338 339 340 341 342 |
# File 'lib/brakeman/util.rb', line 337 def dir_glob? exp exp = exp.block_call if node_type? exp, :iter return unless call? exp (exp.target == DIR_CONST and exp.method == :glob) or dir_glob? exp.target end |
#false?(exp) ⇒ Boolean
Check if exp represents a :false or :nil node
232 233 234 235 |
# File 'lib/brakeman/util.rb', line 232 def false? exp exp.is_a? Sexp and (exp.node_type == :false or exp.node_type == :nil) end |
#hash?(exp) ⇒ Boolean
Check if exp represents a hash: s(:hash, …) This also includes pseudo hashes params, session, and cookies.
172 173 174 175 176 177 |
# File 'lib/brakeman/util.rb', line 172 def hash? exp exp.is_a? Sexp and (exp.node_type == :hash or exp.node_type == :params or exp.node_type == :session or exp.node_type == :cookies) end |
#hash_access(hash, key) ⇒ Object
Get value from hash using key.
If key is a Symbol, it will be converted to a Sexp(:lit, key).
137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/brakeman/util.rb', line 137 def hash_access hash, key if key.is_a? Symbol key = Sexp.new(:lit, key) end if index = hash.find_index(key) and index > 0 return hash[index + 1] end nil end |
#hash_insert(hash, key, value) ⇒ Object
Insert value into Hash Sexp
119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/brakeman/util.rb', line 119 def hash_insert hash, key, value index = 1 hash_iterate hash.dup do |k,v| if k == key hash[index + 1] = value return hash end index += 2 end hash << key << value hash end |
#hash_iterate(hash) ⇒ Object
Takes an Sexp like (:hash, (:lit, :key), (:str, “value”)) and yields the key and value pairs to the given block.
For example:
h = Sexp.new(:hash, (:lit, :name), (:str, “bob”), (:lit, :name), (:str, “jane”)) names = [] hash_iterate(h) do |key, value|
if symbol? key and key[1] == :name
names << value[1]
end
end names #[“bob”]
102 103 104 105 106 107 108 |
# File 'lib/brakeman/util.rb', line 102 def hash_iterate hash hash = remove_kwsplat(hash) 1.step(hash.length - 1, 2) do |i| yield hash[i], hash[i + 1] end end |
#hash_values(hash) ⇒ Object
149 150 151 152 153 154 155 |
# File 'lib/brakeman/util.rb', line 149 def hash_values hash values = hash.each_sexp.each_slice(2).map do |_, value| value end Sexp.new(:array).concat(values).line(hash.line) end |
#integer?(exp) ⇒ Boolean
Check if exp represents an Integer: s(:lit, …)
210 211 212 |
# File 'lib/brakeman/util.rb', line 210 def integer? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Integer end |
#kwsplat?(exp) ⇒ Boolean
299 300 301 302 303 304 |
# File 'lib/brakeman/util.rb', line 299 def kwsplat? exp exp.is_a? Sexp and exp.node_type == :hash and exp[1].is_a? Sexp and exp[1].node_type == :kwsplat end |
#literal?(exp) ⇒ Boolean
324 325 326 |
# File 'lib/brakeman/util.rb', line 324 def literal? exp exp.is_a? Sexp and LITERALS.include? exp.node_type end |
#make_call(target, method, *args) ⇒ Object
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
# File 'lib/brakeman/util.rb', line 363 def make_call target, method, *args call = Sexp.new(:call, target, method) if args.empty? or args.first.empty? #nothing to do elsif node_type? args.first, :arglist call.concat args.first.sexp_body elsif args.first.node_type.is_a? Sexp #just a list of args call.concat args.first else call.concat args end call end |
#node_type?(exp, *types) ⇒ Boolean
Check if exp is a Sexp and the node type matches one of the given types.
312 313 314 |
# File 'lib/brakeman/util.rb', line 312 def node_type? exp, *types exp.is_a? Sexp and types.include? exp.node_type end |
#number?(exp) ⇒ Boolean
Check if exp represents a number: s(:lit, …)
215 216 217 |
# File 'lib/brakeman/util.rb', line 215 def number? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Numeric end |
#params?(exp) ⇒ Boolean
Check if exp is a params hash
244 245 246 |
# File 'lib/brakeman/util.rb', line 244 def params? exp recurse_check?(exp) { |child| child.node_type == :params or ALL_PARAMETERS.include? child } end |
#pluralize(word) ⇒ Object
stupid simple, used to delegate to ActiveSupport
52 53 54 55 56 57 58 |
# File 'lib/brakeman/util.rb', line 52 def pluralize word if word.end_with? 's' word + 'es' else word + 's' end end |
#rails_version ⇒ Object
395 396 397 |
# File 'lib/brakeman/util.rb', line 395 def rails_version @tracker.config.rails_version end |
#recurse_check?(exp, &check) ⇒ Boolean
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/brakeman/util.rb', line 252 def recurse_check? exp, &check if exp.is_a? Sexp return true if yield(exp) if call? exp if recurse_check? exp[1], &check return true elsif exp[2] == :[] return recurse_check? exp[1], &check end end end false end |
#regexp?(exp) ⇒ Boolean
Check if exp represents a Regexp: s(:lit, /…/)
205 206 207 |
# File 'lib/brakeman/util.rb', line 205 def regexp? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Regexp end |
#remove_kwsplat(exp) ⇒ Object
110 111 112 113 114 115 116 |
# File 'lib/brakeman/util.rb', line 110 def remove_kwsplat exp if exp.any? { |e| node_type? e, :kwsplat } exp.reject { |e| node_type? e, :kwsplat } else exp end end |
#request_headers?(exp) ⇒ Boolean
Only return true when accessing request headers via request.env
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/brakeman/util.rb', line 269 def request_headers? exp return unless sexp? exp if exp[1] == REQUEST_ENV if exp.method == :[] if string? exp.first_arg # Only care about HTTP headers, which are prefixed by 'HTTP_' exp.first_arg.value.start_with?('HTTP_'.freeze) else true # request.env[something] end else false # request.env.something end else false end end |
#request_value?(exp) ⇒ Boolean
Check if exp is params, cookies, or request_headers
289 290 291 292 293 |
# File 'lib/brakeman/util.rb', line 289 def request_value? exp params? exp or exp or request_headers? exp end |
#result?(exp) ⇒ Boolean
Check if exp represents a result: s(:result, …)
220 221 222 |
# File 'lib/brakeman/util.rb', line 220 def result? exp exp.is_a? Sexp and exp.node_type == :result end |
#safe_literal(line = nil) ⇒ Object
379 380 381 |
# File 'lib/brakeman/util.rb', line 379 def safe_literal line = nil s(:lit, :BRAKEMAN_SAFE_LITERAL).line(line || 0) end |
#safe_literal?(exp) ⇒ Boolean
383 384 385 |
# File 'lib/brakeman/util.rb', line 383 def safe_literal? exp exp == SAFE_LITERAL end |
#safe_literal_target?(exp) ⇒ Boolean
387 388 389 390 391 392 393 |
# File 'lib/brakeman/util.rb', line 387 def safe_literal_target? exp if call? exp safe_literal_target? exp.target else safe_literal? exp end end |
#set_env_defaults ⇒ Object
Adds params, session, and cookies to environment so they can be replaced by their respective Sexps.
164 165 166 167 168 |
# File 'lib/brakeman/util.rb', line 164 def set_env_defaults @env[PARAMETERS] = PARAMS_SEXP @env[SESSION] = SESSION_SEXP @env[COOKIES] = COOKIES_SEXP end |
#sexp?(exp) ⇒ Boolean
Check if exp is a Sexp.
307 308 309 |
# File 'lib/brakeman/util.rb', line 307 def sexp? exp exp.is_a? Sexp end |
#simple_literal?(exp) ⇒ Boolean
318 319 320 |
# File 'lib/brakeman/util.rb', line 318 def simple_literal? exp exp.is_a? Sexp and SIMPLE_LITERALS.include? exp.node_type end |
#string?(exp) ⇒ Boolean
Check if exp represents a String: s(:str, “…”)
185 186 187 |
# File 'lib/brakeman/util.rb', line 185 def string? exp exp.is_a? Sexp and exp.node_type == :str end |
#string_interp?(exp) ⇒ Boolean
189 190 191 |
# File 'lib/brakeman/util.rb', line 189 def string_interp? exp exp.is_a? Sexp and exp.node_type == :dstr end |
#symbol?(exp) ⇒ Boolean
Check if exp represents a Symbol: s(:lit, :…)
194 195 196 |
# File 'lib/brakeman/util.rb', line 194 def symbol? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Symbol end |
#template_path_to_name(path) ⇒ Object
Convert path/filename to view name
views/test/something.html.erb -> test/something
402 403 404 405 406 407 408 409 410 411 |
# File 'lib/brakeman/util.rb', line 402 def template_path_to_name path names = path.relative.split('/') names.last.gsub!(/(\.(html|js)\..*|\.(rhtml|haml|erb|slim))$/, '') if names.include? 'views' names[(names.index('views') + 1)..-1] else names end.join('/').to_sym end |
#true?(exp) ⇒ Boolean
Check if exp represents a :true, :lit, or :string node
225 226 227 228 229 |
# File 'lib/brakeman/util.rb', line 225 def true? exp exp.is_a? Sexp and (exp.node_type == :true or exp.node_type == :lit or exp.node_type == :string) end |
#underscore(camel_cased_word) ⇒ Object
Convert a string from “Something::LikeThis” to “something/like_this”
Taken from ActiveSupport.
43 44 45 46 47 48 49 |
# File 'lib/brakeman/util.rb', line 43 def underscore camel_cased_word camel_cased_word.to_s.gsub(/::/, '/'). gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2'). tr("-", "_"). downcase end |