-
Notifications
You must be signed in to change notification settings - Fork 2.2k
(PUP-8969) Preserve sensitiveness of epp templates #8330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This still needs tests. Given the manifest: $result = inline_epp("This is sensitive: <%= Sensitive.new('sesame') %>\n")
notify { 'message':
message => $result
}
file { '/tmp/sensitive.txt':
ensure => file,
content => $result,
} Previously the file contained the redacted string
With this PR, the file contains the unwrapped value. Also note the changes to the
Also if the manifest already wraps the content in sensitive: $result = inline_epp("This is sensitive: <%= Sensitive.new('sesame') %>\n")
file { '/tmp/sensitive.txt':
ensure => file,
content => Sensitive.new($result),
} Then the result is still correct (it doesn't double wrap). So I believe this is backwards compatible with existing manifests:
|
CLA signed by all contributors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like the desired behavior and the code looks good. I didn't see anything weird in the ast hierarchy that would require changing other classes.
I think there's an edge case if someone is putting an epp result into a typed variable where this will be backwards incompatible. eg.
String $foo = epp(...)
$final = $foo.regsubst(//, '')
However that's a weird use case (ie you should just change the template rather than acting on the content post rendering) and I'm not too concerned it changing to fix this issue.
That's a great point... and yes it fails:
|
Following up after chatting with @npwalker and @reidmv. So up until now, if a sensitive value is not explicitly unwrapped in a template via This PR eliminates the trashing around so the following just work: file { '/tmp/app.conf':
ensure => file,
content => inline_epp("token: <%= Sensitive.new('opensesame') %>"),
} This PR will is also compatible with existing manifests which unwrap and rewrap the sensitive value: file { '/tmp/app.conf':
ensure => file,
content => Sensitive.new(inline_epp("token: <%= Sensitive.new('opensesame').unwrap %>")),
} |
eb45779
to
bd43992
Compare
If an EPP template contains a Sensitive data type, then join the unwrapped value, but wrap the entire result as Sensitive. This way the underlying sensitive value is preserved, and the caller can access it by unwrapping the entire result. Previously, the result was always a string and contained the generic 'Sensitive [redacted]' message, so the underlying sensitive value was lost. Update the `epp` and `inline_epp` function signatures, since they can both return either String or Sensitive[String]. Update the `epp` application to unwrap sensitive values produced by the above functions.
bd43992
to
10724d7
Compare
END | ||
expect(catalog.resource(:notify, 'title')['message']).to eq('opensesame') | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% about the location of these tests, but the second and third tests fail as expected when run against puppet code that doesn't have this change:
1) the inline_epp function when using Sensitive rewraps a sensitive value
Failure/Error:
expect(eval_and_collect_notices(<<~END)).to eq(["Sensitive [value redacted]"])
notice(inline_epp("This is <%= Sensitive('opensesame') %>"))
END
expected: ["Sensitive [value redacted]"]
got: ["This is sensitive Sensitive [value redacted]"]
(compared using ==)
# ./spec/unit/functions/inline_epp_spec.rb:87:in `block (3 levels) in <top (required)>'
# ./spec/spec_helper.rb:180:in `block (2 levels) in <top (required)>'
# ./.bundle/ruby/2.7.0/gems/webmock-3.9.3/lib/webmock/rspec.rb:37:in `block (2 levels) in <top (required)>'
2) the inline_epp function when using Sensitive can be double wrapped
Failure/Error: expect(catalog.resource(:notify, 'title')['message']).to eq('opensesame')
expected: "opensesame"
got: "Sensitive [value redacted]"
(compared using ==)
# ./spec/unit/functions/inline_epp_spec.rb:98:in `block (3 levels) in <top (required)>'
# ./spec/spec_helper.rb:180:in `block (2 levels) in <top (required)>'
# ./.bundle/ruby/2.7.0/gems/webmock-3.9.3/lib/webmock/rspec.rb:37:in `block (2 levels) in <top (required)>'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the location is weird, there's 4 places that these changes could be (evaluator, face, inline_epp, and epp) but to actually put something in those places is largely copying the same tests around.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems correct to the final request in the ticket.
If none of the input variables are `Deferred`, then `deferrable_epp` returns the result of calling normal `epp`. The `epp` function however will return a `Sensitive` if any of the variables it was called with were `Sensitive`. See puppetlabs/puppet#8330 Adding `Sensitive[String]` to the list of allowed return types fixes this.
If none of the input variables are `Deferred`, then `deferrable_epp` returns the result of calling normal `epp`. The `epp` function however will return a `Sensitive` if any of the variables it was called with were `Sensitive`. See puppetlabs/puppet#8330 Adding `Sensitive[String]` to the list of allowed return types fixes this.
If an EPP template contains a Sensitive data type, then join the unwrapped
value, but wrap the entire result as Sensitive. This way the underlying
sensitive value is preserved, and the caller can access it by unwrapping the
entire result. Previously, the result was always a string and contained the
generic 'Sensitive [redacted]' message, so the underlying sensitive value was
lost.
Update the
epp
andinline_epp
function signatures, since they can bothreturn either String or Sensitive[String].
Update the
epp
application to unwrap sensitive values produced by the abovefunctions.