Skip to content

Commit

Permalink
fix masking of multiline secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
wr0ngway committed Jun 23, 2021
1 parent bf4bf81 commit 88c8676
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
18 changes: 11 additions & 7 deletions lib/kubetruth/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,27 +125,31 @@ def initialize(template_source)
def render(*args, **kwargs)
begin

# TODO: fix secrets hardcoding here
secrets = kwargs[:secrets] || {}
debug_kwargs = nil

logger.debug do
# TODO: fix secrets hardcoding here
debug_kwargs ||= kwargs.merge(secrets: Hash[secrets.collect {|k, v| [k, "<masked:#{k}>"] }])
msg = "Evaluating template:\n"
@source.to_s.lines.collect {|l| msg << (INDENT * 2) << l }
msg << "\n" << INDENT << "with context:\n"
kwargs.deep_stringify_keys.to_yaml.lines.collect {|l| msg << (INDENT * 2) << l }

secrets.each {|k, v| msg.gsub!(v, "<masked:#{k}>") }
debug_kwargs.deep_stringify_keys.to_yaml.lines.collect {|l| msg << (INDENT * 2) << l }
msg
end

result = @liquid.render!(*args, kwargs.stringify_keys, strict_variables: true, strict_filters: true)

logger.debug do
debug_kwargs ||= kwargs.merge(secrets: Hash[secrets.collect {|k, v| [k, "<masked:#{k}>"] }])
# we only ever have to sub base64 encoded in this debug block
both_secrets = secrets.merge(Hash[secrets.collect {|k, v| ["#{k}_base64", Base64.strict_encode64(v)]}])

msg = "Rendered template:\n"
result.lines.collect {|l| msg << (INDENT * 2) << l }
both_secrets.each {|k, v| msg.gsub!(v, "<masked:#{k}>") }
r = result.dup
both_secrets.each {|k, v| r = r.gsub!(v, "<masked:#{k}>") }
r.lines.collect {|l| msg << (INDENT * 2) << l }
msg
end

Expand All @@ -157,9 +161,9 @@ def render(*args, **kwargs)
msg << INDENT << "with error message:\n" << (INDENT * 2) << "#{e.message}"
if e.is_a?(Liquid::UndefinedVariable)
msg << "\n" << INDENT << "and variable context:\n"
kwargs.deep_stringify_keys.to_yaml.lines.collect {|l| msg << (INDENT * 2) << l }
debug_kwargs ||= kwargs.merge(secrets: Hash[secrets.collect {|k, v| [k, "<masked:#{k}>"] }])
debug_kwargs.deep_stringify_keys.to_yaml.lines.collect {|l| msg << (INDENT * 2) << l }
end
secrets.each {|k, v| msg.gsub!(v, "<masked:#{k}>") }
raise Error, msg
end
end
Expand Down
18 changes: 18 additions & 0 deletions spec/kubetruth/template_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,27 @@ module Kubetruth
expect(error.message).to_not include(Base64.strict_encode64("sekret"))
expect(error.message).to_not include("<masked:foo_base64>")
end
end

it "masks multiline secrets in logs" do
secrets = {"foo" => "sekret\nsosekret"}
tmpl = described_class.new("secret: {{secrets.foo}} encoded: {{secrets.foo | encode64}}")
expect(tmpl.render(secrets: secrets)).to eq("secret: sekret\nsosekret encoded: #{Base64.strict_encode64("sekret\nsosekret")}")
expect(Logging.contents).to_not include("sekret")
expect(Logging.contents).to include("<masked:foo>")
expect(Logging.contents).to_not include(Base64.strict_encode64("sekret\nsosekret"))
expect(Logging.contents).to include("<masked:foo_base64>")

tmpl = described_class.new("{{fail}}")
expect { tmpl.render(secrets: secrets) }.to raise_error(Template::Error) do |error|
expect(error.message).to_not include("sekret")
expect(error.message).to include("<masked:foo>")
expect(error.message).to_not include(Base64.strict_encode64("sekret\nsosekret"))
expect(error.message).to_not include("<masked:foo_base64>")
end
end


end

end
Expand Down

0 comments on commit 88c8676

Please sign in to comment.