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
326 327 328 329 330 |
# File 'lib/brakeman/util.rb', line 326 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, […])
178 179 180 |
# File 'lib/brakeman/util.rb', line 178 def array? exp exp.is_a? Sexp and exp.node_type == :array end |
#block?(exp) ⇒ Boolean
Check if exp represents a block of code
236 237 238 239 |
# File 'lib/brakeman/util.rb', line 236 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, …)
197 198 199 200 |
# File 'lib/brakeman/util.rb', line 197 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 |
# File 'lib/brakeman/util.rb', line 62 def class_name exp case exp when Sexp case exp.node_type when :const, :colon3 exp.value when :lvar exp.value.to_sym when :colon2 "#{class_name(exp.lhs)}::#{exp.rhs}".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
293 294 295 |
# File 'lib/brakeman/util.rb', line 293 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.
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/brakeman/util.rb', line 345 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
246 247 248 |
# File 'lib/brakeman/util.rb', line 246 def exp recurse_check?(exp) { |child| child.node_type == :cookies or ALL_COOKIES.include? child } end |
#dir_glob?(exp) ⇒ Boolean
Dir.glob(…).whatever
335 336 337 338 339 340 |
# File 'lib/brakeman/util.rb', line 335 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
230 231 232 233 |
# File 'lib/brakeman/util.rb', line 230 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.
170 171 172 173 174 175 |
# File 'lib/brakeman/util.rb', line 170 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).
135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/brakeman/util.rb', line 135 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
117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/brakeman/util.rb', line 117 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”]
100 101 102 103 104 105 106 |
# File 'lib/brakeman/util.rb', line 100 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
147 148 149 150 151 152 153 |
# File 'lib/brakeman/util.rb', line 147 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, …)
208 209 210 |
# File 'lib/brakeman/util.rb', line 208 def integer? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Integer end |
#kwsplat?(exp) ⇒ Boolean
297 298 299 300 301 302 |
# File 'lib/brakeman/util.rb', line 297 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
322 323 324 |
# File 'lib/brakeman/util.rb', line 322 def literal? exp exp.is_a? Sexp and LITERALS.include? exp.node_type end |
#make_call(target, method, *args) ⇒ Object
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/brakeman/util.rb', line 361 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.
310 311 312 |
# File 'lib/brakeman/util.rb', line 310 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, …)
213 214 215 |
# File 'lib/brakeman/util.rb', line 213 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
242 243 244 |
# File 'lib/brakeman/util.rb', line 242 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
393 394 395 |
# File 'lib/brakeman/util.rb', line 393 def rails_version @tracker.config.rails_version end |
#recurse_check?(exp, &check) ⇒ Boolean
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/brakeman/util.rb', line 250 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, /…/)
203 204 205 |
# File 'lib/brakeman/util.rb', line 203 def regexp? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Regexp end |
#remove_kwsplat(exp) ⇒ Object
108 109 110 111 112 113 114 |
# File 'lib/brakeman/util.rb', line 108 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
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/brakeman/util.rb', line 267 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
287 288 289 290 291 |
# File 'lib/brakeman/util.rb', line 287 def request_value? exp params? exp or exp or request_headers? exp end |
#result?(exp) ⇒ Boolean
Check if exp represents a result: s(:result, …)
218 219 220 |
# File 'lib/brakeman/util.rb', line 218 def result? exp exp.is_a? Sexp and exp.node_type == :result end |
#safe_literal(line = nil) ⇒ Object
377 378 379 |
# File 'lib/brakeman/util.rb', line 377 def safe_literal line = nil s(:lit, :BRAKEMAN_SAFE_LITERAL).line(line || 0) end |
#safe_literal?(exp) ⇒ Boolean
381 382 383 |
# File 'lib/brakeman/util.rb', line 381 def safe_literal? exp exp == SAFE_LITERAL end |
#safe_literal_target?(exp) ⇒ Boolean
385 386 387 388 389 390 391 |
# File 'lib/brakeman/util.rb', line 385 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.
162 163 164 165 166 |
# File 'lib/brakeman/util.rb', line 162 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.
305 306 307 |
# File 'lib/brakeman/util.rb', line 305 def sexp? exp exp.is_a? Sexp end |
#simple_literal?(exp) ⇒ Boolean
316 317 318 |
# File 'lib/brakeman/util.rb', line 316 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, “…”)
183 184 185 |
# File 'lib/brakeman/util.rb', line 183 def string? exp exp.is_a? Sexp and exp.node_type == :str end |
#string_interp?(exp) ⇒ Boolean
187 188 189 |
# File 'lib/brakeman/util.rb', line 187 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, :…)
192 193 194 |
# File 'lib/brakeman/util.rb', line 192 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
400 401 402 403 404 405 406 407 408 409 |
# File 'lib/brakeman/util.rb', line 400 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
223 224 225 226 227 |
# File 'lib/brakeman/util.rb', line 223 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 |