Class/Module Index [+]

Quicksearch

Brakeman::CheckContentTag

Checks for unescaped values in `content_tag`

content_tag :tag, body
                   ^-- Unescaped in Rails 2.x

content_tag, :tag, body, attribute => value
                            ^-- Unescaped in all versions

content_tag, :tag, body, attribute => value
                                        ^
                                        |
        Escaped by default, can be explicitly escaped
        or not by passing in (true|false) as fourth argument

Public Instance Methods

check_argument(result, exp) click to toggle source
# File lib/brakeman/checks/check_content_tag.rb, line 87
def check_argument result, exp
  #Check contents of raw() calls directly
  if call? exp and exp.method == :raw
    arg = process exp.first_arg
  else
    arg = process exp
  end

  if input = has_immediate_user_input?(arg)
    case input.type
    when :params
      message = "Unescaped parameter value in content_tag"
    when :cookies
      message = "Unescaped cookie value in content_tag"
    else
      message = "Unescaped user input value in content_tag"
    end

    add_result result

    warn :result => result,
      :warning_type => "Cross Site Scripting", 
      :message => message,
      :user_input => input.match,
      :confidence => CONFIDENCE[:high],
      :link_path => "content_tag"

  elsif not tracker.options[:ignore_model_output] and match = has_immediate_model?(arg)
    method = match[2]

    unless IGNORE_MODEL_METHODS.include? method
      add_result result

      if MODEL_METHODS.include? method or method.to_s =~ /^find_by/
        confidence = CONFIDENCE[:high]
      else
        confidence = CONFIDENCE[:med]
      end

      warn :result => result,
        :warning_type => "Cross Site Scripting", 
        :message => "Unescaped model attribute in content_tag",
        :user_input => match,
        :confidence => confidence,
        :link_path => "content_tag"
    end

  elsif @matched
    message = "Unescaped "

    case @matched.type
    when :model
      return if tracker.options[:ignore_model_output]
      message << "model attribute"
    when :params
      message << "parameter"
    when :cookies
      message << "cookie"
    when :session
      message << "session"
    else
      message << "user input"
    end

    message << " value in content_tag"

    add_result result

    warn :result => result, 
      :warning_type => "Cross Site Scripting", 
      :message => message,
      :user_input => @matched.match,
      :confidence => CONFIDENCE[:med],
      :link_path => "content_tag"
    end
end
process_call(exp) click to toggle source
# File lib/brakeman/checks/check_content_tag.rb, line 164
def process_call exp
  if @mark
    actually_process_call exp
  else
    @mark = true
    actually_process_call exp
    @mark = false
  end

  exp
end
process_result(result) click to toggle source
# File lib/brakeman/checks/check_content_tag.rb, line 42
def process_result result
  return if duplicate? result

  call = result[:call] = result[:call].dup

  args = call.arglist 

  tag_name = args[1]
  content = args[2]
  attributes = args[3]
  escape_attr = args[4]

  @matched = false

  #Silly, but still dangerous if someone uses user input in the tag type
  check_argument result, tag_name

  #Versions before 3.x do not escape body of tag, nor does the rails_xss gem
  unless @matched or (tracker.options[:rails3] and not raw? content)
    check_argument result, content
  end

  #Attribute keys are never escaped, so check them for user input
  if not @matched and hash? attributes and not request_value? attributes
    hash_iterate(attributes) do |k, v|
      check_argument result, k
      return if @matched
    end
  end

  #By default, content_tag escapes attribute values passed in as a hash.
  #But this behavior can be disabled. So only check attributes hash
  #if they are explicitly not escaped.
  if not @matched and attributes and false? escape_attr
    if request_value? attributes or not hash? attributes
      check_argument result, attributes
    else #check hash values
      hash_iterate(attributes) do |k, v|
        check_argument result, v
        return if @matched
      end
    end
  end
end
raw?(exp) click to toggle source
# File lib/brakeman/checks/check_content_tag.rb, line 176
def raw? exp
  call? exp and exp.method == :raw
end
run_check() click to toggle source
# File lib/brakeman/checks/check_content_tag.rb, line 21
def run_check
  @ignore_methods = Set[:button_to, :check_box, :escapeHTML, :escape_once,
                         :field_field, :fields_for, :h, :hidden_field,
                         :hidden_field, :hidden_field_tag, :image_tag, :label,
                         :mail_to, :radio_button, :select,
                         :submit_tag, :text_area, :text_field,
                         :text_field_tag, :url_encode, :url_for,
                         :will_paginate].merge tracker.options[:safe_methods]

  @known_dangerous = []
  methods = tracker.find_call :target => false, :method => :content_tag

  @models = tracker.models.keys
  @inspect_arguments = tracker.options[:check_arguments]

  Brakeman.debug "Checking for XSS in content_tag"
  methods.each do |call|
    process_result call
  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.