Sha256: f2e1b0b6a4ebc65e9f956d73dbc40b8f2a14a8408459cbe15763ce58e8457326

Contents?: true

Size: 1.3 KB

Versions: 2

Compression:

Stored size: 1.3 KB

Contents

# frozen_string_literal: true

module TaintedLove
  module Replacer
    class ReplaceRackBuilder < Base
      def should_replace?
        Object.const_defined?('Rack::Builder')
      end

      def replace!
        # Register a middleware that will be the first the receive call and prepare the
        # env to be correctly tainted. This should be enough for all Rack-based apps
        TaintedLove.proxy_method('Rack::Builder', :run) do |_, app, builder|
          builder.use(TaintedLove::Replacer::ReplaceRackBuilder::TaintedLoveRackMiddleware)
        end
      end

      class TaintedLoveRackMiddleware
        def initialize(app)
          @app = app
        end

        def call(env)
          @app.call(taint_env(env))
        end

        def taint_env(env)
          uppercase_keys = env.to_h.keys.select { |k| k[/[A-Z]/] }

          values = {}
          uppercase_keys.each do |key|
            new_key = key.dup.taint
            new_value = env[key].dup.taint

            TaintedLove.tag(new_key, source: "Key #{key.inspect} Rack env", value: new_key)
            TaintedLove.tag(new_value, source: "Rack env[#{key.inspect}]", value: new_value)

            values[new_key] = new_value

            env.delete(key)
          end

          env.merge!(values)

          env
        end
      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_builder.rb
tainted_love-0.4.0 lib/tainted_love/replacer/replace_rack_builder.rb