module Brakeman::Util
This is a mixin containing utility methods.
Constants
- ALL_COOKIES
- ALL_PARAMETERS
- COOKIES
- COOKIES_SEXP
- DIR_CONST
- LITERALS
- PARAMETERS
- PARAMS_SEXP
These are never modified
- PATH_PARAMETERS
- QUERY_PARAMETERS
- REQUEST_COOKIES
- REQUEST_ENV
- REQUEST_PARAMETERS
- REQUEST_PARAMS
- REQUEST_REQUEST_PARAMETERS
- SAFE_LITERAL
- SESSION
- SESSION_SEXP
- SIMPLE_LITERALS
Public Instance Methods
# 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
Check if exp represents an array: s(:array, […])
# File lib/brakeman/util.rb, line 178 def array? exp exp.is_a? Sexp and exp.node_type == :array end
Check if exp represents a block of code
# 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
Check if exp represents a method call: s(:call, …)
# 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
Convert a string from “something_like_this” to “SomethingLikeThis”
Taken from ActiveSupport.
# 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
Returns a class name as a Symbol. If class name cannot be determined, returns exp.
# 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
# File lib/brakeman/util.rb, line 293 def constant? exp node_type? exp, :const, :colon2, :colon3 end
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.
# 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
Dir.glob(…).whatever
# 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
Check if exp represents a :false or :nil node
# 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
Check if exp represents a hash: s(:hash, {…}) This also includes pseudo hashes params, session, and cookies.
# 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
Get value from hash using key.
If key is a Symbol, it will be converted to a Sexp(:lit, key).
# 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
Insert value into Hash Sexp
# 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
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"]
# 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
# 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
Check if exp represents an Integer: s(:lit, …)
# 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
# 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
# File lib/brakeman/util.rb, line 322 def literal? exp exp.is_a? Sexp and LITERALS.include? exp.node_type end
# 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
Check if exp is a Sexp
and the node type matches one of the given types.
# File lib/brakeman/util.rb, line 310 def node_type? exp, *types exp.is_a? Sexp and types.include? exp.node_type end
Check if exp represents a number: s(:lit, …)
# 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
Check if exp is a params hash
# File lib/brakeman/util.rb, line 242 def params? exp recurse_check?(exp) { |child| child.node_type == :params or ALL_PARAMETERS.include? child } end
stupid simple, used to delegate to ActiveSupport
# File lib/brakeman/util.rb, line 52 def pluralize word if word.end_with? 's' word + 'es' else word + 's' end end
# File lib/brakeman/util.rb, line 393 def rails_version @tracker.config.rails_version end
# 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
Check if exp represents a Regexp: s(:lit, /…/)
# 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
# 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
Only return true when accessing request headers via request.env
# 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
Check if exp is params, cookies, or request_headers
# File lib/brakeman/util.rb, line 287 def request_value? exp params? exp or cookies? exp or request_headers? exp end
Check if exp represents a result: s(:result, …)
# File lib/brakeman/util.rb, line 218 def result? exp exp.is_a? Sexp and exp.node_type == :result end
# File lib/brakeman/util.rb, line 377 def safe_literal line = nil s(:lit, :BRAKEMAN_SAFE_LITERAL).line(line || 0) end
# File lib/brakeman/util.rb, line 381 def safe_literal? exp exp == SAFE_LITERAL end
# 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
Adds params, session, and cookies to environment so they can be replaced by their respective Sexps.
# File lib/brakeman/util.rb, line 162 def set_env_defaults @env[PARAMETERS] = PARAMS_SEXP @env[SESSION] = SESSION_SEXP @env[COOKIES] = COOKIES_SEXP end
Check if exp is a Sexp
.
# File lib/brakeman/util.rb, line 305 def sexp? exp exp.is_a? Sexp end
# File lib/brakeman/util.rb, line 316 def simple_literal? exp exp.is_a? Sexp and SIMPLE_LITERALS.include? exp.node_type end
Check if exp represents a String: s(:str, “…”)
# File lib/brakeman/util.rb, line 183 def string? exp exp.is_a? Sexp and exp.node_type == :str end
# File lib/brakeman/util.rb, line 187 def string_interp? exp exp.is_a? Sexp and exp.node_type == :dstr end
Check if exp represents a Symbol: s(:lit, :…)
# 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
Convert path/filename to view name
views/test/something.html.erb -> test/something
# 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
Check if exp represents a :true, :lit, or :string node
# 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
Convert a string from “Something::LikeThis” to “something/like_this”
Taken from ActiveSupport.
# 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