无法使用VCR过滤敏感数据

时间:2015-08-05 20:16:32

标签: ruby-on-rails replace vcr

我的spec_helper

中有以下内容
c.filter_sensitive_data("<FILTERED>") { keys['s3_key'] }
c.filter_sensitive_data("<REDACTED>") { keys['s3_secret'] }

然而,当我运行我的规范时,我发现它在磁带中创建了以下条目:

Authorization:
- AWS <FILTERED>:this_part_has_not_been_filtered=

如您所见,有一部分尚未过滤。我不确定它是否包含有用信息,但我不想仅仅粘贴它。但我可以说它不包含我的钥匙或我的秘密。它只是绒毛吗?我应该关心吗?这是在使用aws-sdk gem时过滤S3请求时通常会发生的情况吗?如果没有,那么如何才能过滤所有授权数据呢?

是否有一组特殊的过滤S3键的说明?我真的不想搞砸了。

1 个答案:

答案 0 :(得分:2)

好吧,如果你的钥匙不在那里,看起来很安全。可以肯定的是,您可以使用regexp matcher来替换整个字符串,例如%r<#{keys['s3_key']:.*?=>。坏消息:没有正则表达式filter_sensitive_data。好消息:您可以使用更多低级方法自行实现。

filter_sensitive_data

的当前实施情况
# @param placeholder [String] The placeholder string.
# @param tag [Symbol] Set this to apply this only to cassettes
#  with a matching tag; otherwise it will apply to every cassette.
# @yield block that determines what string to replace
# @yieldparam interaction [(optional) VCR::HTTPInteraction::HookAware] the HTTP interaction
# @yieldreturn the string to replace
def define_cassette_placeholder(placeholder, tag = nil, &block)
  before_record(tag) do |interaction|
    orig_text = call_block(block, interaction)
    log "before_record: replacing #{orig_text.inspect} with #{placeholder.inspect}"
    interaction.filter!(orig_text, placeholder)
  end

  before_playback(tag) do |interaction|
    orig_text = call_block(block, interaction)
    log "before_playback: replacing #{placeholder.inspect} with #{orig_text.inspect}"
    interaction.filter!(placeholder, orig_text)
  end
end
alias filter_sensitive_data define_cassette_placeholder

Source

这引导我们采用这些方法

  # Replaces a string in any part of the HTTP interaction (headers, request body,
  # response body, etc) with the given replacement text.
  #
  # @param [#to_s] text the text to replace
  # @param [#to_s] replacement_text the text to put in its place
  def filter!(text, replacement_text)
    text, replacement_text = text.to_s, replacement_text.to_s
    return self if [text, replacement_text].any? { |t| t.empty? }
    filter_object!(self, text, replacement_text)
  end

private

  def filter_object!(object, text, replacement_text)
    if object.respond_to?(:gsub)
      object.gsub!(text, replacement_text) if object.include?(text)
    elsif Hash === object
      filter_hash!(object, text, replacement_text)
    elsif object.respond_to?(:each)
      # This handles nested arrays and structs
      object.each { |o| filter_object!(o, text, replacement_text) }
    end

    object
  end

Source

哦,我们可能会尝试使用猴子修补此方法:

spec_helper中的某个地方

class VCR::HTTPInteraction::HookAware
  def filter!(text, replacement_text)
    replacement_text = replacement_text.to_s unless replacement_text.is_a?(Regexp)
    text = text.to_s
    return self if [text, replacement_text].any? { |t| t.empty? }
    filter_object!(self, text, replacement_text)
  end
end

当然,你可以选择不搞外星人图书馆的深层内部,并且不要觉得过于偏执,知道一些随机的字母数字数据被写入你的令牌附近的卡带(但不包括后者) )。