-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Ensure error messages don't leak private key #11523
base: master
Are you sure you want to change the base?
Ensure error messages don't leak private key #11523
Conversation
@@ -14,6 +14,9 @@ private: | |||
const std::string host; | |||
bool fakeSSH; | |||
const std::string keyFile; | |||
/** | |||
* Raw bytes, not Base64 encoding. | |||
*/ | |||
const std::string sshPublicHostKey; |
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.
If it's raw bytes, then should it really still be std::string
and not something like std::vector<u8>
or something?
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.
Probably, but doing that better would require more changes (because we use std::string
in a few places for this) so I think it's best we keep it future work.
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 always felt that c++ string is just the same as a std::vector in other languages.
src/libutil/util.hh
Outdated
std::string base64Encode(std::string_view s); | ||
std::string base64Decode(std::string_view s); | ||
|
||
/** | ||
* Decode arbitrary bytes to Base64. | ||
* | ||
* @param hideValue Avoid displaying the raw Base64 in error messages, | ||
* e.g. to avoid leaking private keys. | ||
*/ | ||
std::string base64Decode(std::string_view s, bool hideValue = false); |
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.
@cole-h e.g. these type signatures (strings on both sides) are also not instructive
src/libutil/util.cc
Outdated
@@ -220,7 +220,7 @@ std::string base64Encode(std::string_view s) | |||
} | |||
|
|||
|
|||
std::string base64Decode(std::string_view s) | |||
std::string base64Decode(std::string_view s, bool hideValue) |
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.
is it normal in c++ that the default value only needs to be set in the prototype but not here?
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.
Yes. I think it will in fact not let you put it in both places.
src/libutil/util.hh
Outdated
* @param hideValue Avoid displaying the raw Base64 in error messages, | ||
* e.g. to avoid leaking private keys. | ||
*/ | ||
std::string base64Decode(std::string_view s, bool hideValue = false); |
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.
Not a strong opinion but to me this seems more intuitive:
std::string base64Decode(std::string_view s, bool hideValue = false); | |
std::string base64Decode(std::string_view s, bool sensitiveValue = false); |
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.
Did the rename
Since NixOS#8766, invalid base64 is rendered in errors, but we don't actually want to show this in the case of an invalid private keys.
18f855c
to
d8b3626
Compare
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.
Still not safe enough, and please add a functional test - see comment.
try { | ||
base64Decode(msg, true); | ||
} catch (FormatError & e) { | ||
EXPECT_THAT(e.msg(), testing::Not(testing::HasSubstr(msg))); |
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.
EXPECT_THAT(e.msg(), testing::Not(testing::HasSubstr(msg))); | |
EXPECT_THAT(e.msg(), testing::Not(testing::HasSubstr(msg))); | |
EXPECT_THAT(e.what(), testing::Not(testing::HasSubstr(msg))); |
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 is still not future proof; please also add a functional test, which will cover the eventuality that yet another method is used for retrieving the message (e.g. something more structured than a string).
* @param sensitiveValue Avoid displaying the raw Base64 in error messages, | ||
* e.g. to avoid leaking private keys. | ||
*/ | ||
std::string base64Decode(std::string_view s, bool sensitiveValue = false); |
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.
std::string base64Decode(std::string_view s, bool sensitiveValue = false); | |
std::string base64Decode(std::string_view s, bool sensitiveValue); |
Each caller should just make a decision.
Or, if we disagree, it should fail safely:
std::string base64Decode(std::string_view s, bool sensitiveValue = false); | |
std::string base64Decode(std::string_view s, bool sensitiveValue = true); |
Add release blocker label because this fixes a minor security regression that's not been released yet. |
Motivation
Since #8766, invalid base64 is rendered in errors, but we don't actually want to show this in the case of an invalid private keys.
Context
#8766
Priorities and Process
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.