Sha256: 9a0244d3da5e12d52bcf0348cf6814e315db024a342924fde14e954e83d930dd

Contents?: true

Size: 1.36 KB

Versions: 2

Compression:

Stored size: 1.36 KB

Contents

# frozen_string_literal: true

module TaintedLove
  module Replacer
    class ReplaceRackRequest < Base

      def replace!
        block = method(:taint_params)

        TaintedLove.proxy_method('Rack::QueryParser', :parse_nested_query, &block)
        TaintedLove.proxy_method('Rack::QueryParser', :parse_query, &block)
      end

      def taint_params(return_value, *args)
        # Assume that if tainted input uses this method, it's to parse a query string
        # It can also be cookies that are being parsed.
        return unless args.first.tainted?

        # figure out what is being parsed from the the method that called it
        name = if Thread.current.backtrace(4).first["`parse_cookies_header'"]
          'cookies'
        else
          'params'
        end

        taint = lambda do |params, path|
          source = name + path.map { |p| "[#{p.inspect}]" }.join

          if params.is_a?(String)
            TaintedLove.tag(params.taint, source: source, value: params)
          end

          if params.is_a?(Array)
            params.each.with_index do |value, index|
              taint.(value, path + [index])
            end
          end

          if params.is_a?(Hash)
            params.each do |key, value|
              taint.(value, path + [key])
            end
          end
        end

        taint.(return_value, [])
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
tainted_love-0.4.1 lib/tainted_love/replacer/replace_rack_query_parser.rb
tainted_love-0.4.0 lib/tainted_love/replacer/replace_rack_query_parser.rb