-
Notifications
You must be signed in to change notification settings - Fork 929
feat: add basic-auth-hash-password flag for encrypted basic auth #1066
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
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1066 +/- ##
==========================================
- Coverage 81.86% 81.82% -0.05%
==========================================
Files 20 20
Lines 2636 2652 +16
==========================================
+ Hits 2158 2170 +12
- Misses 358 362 +4
Partials 120 120 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Pull Request Test Coverage Report for Build 19915781886Details
💛 - Coveralls |
|
Thanks for the PR! |
exporter/http.go
Outdated
| if !authHeaderSet { | ||
| return errors.New("Unauthorized") | ||
| } | ||
| if err := e.verifyBasicUser(user); err != nil { |
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.
nit: verifyBasicUser --> verifyBasicAuthUser ?
exporter/http.go
Outdated
| passCorrect := subtle.ConstantTimeCompare([]byte(password), []byte(e.options.BasicAuthPassword)) | ||
|
|
||
| if userCorrect == 0 || passCorrect == 0 { | ||
| if passCorrect == 0 { |
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 think we should keep the same pattern of always comparing both username and password to avoid timing attacks.
I'd rewrite verifyBasicAuth() and check username first (store result in "userCorrect" and then the password (depending on hash or basic) and store the result in "passCorrect" - then check and return)
main.go
Outdated
| return nil | ||
| } | ||
|
|
||
| // validateHashPassword checks if the the hashed password is a valid bcrypt hash |
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.
👍
main.go
Outdated
| } | ||
|
|
||
| // Validate basic auth hashed password | ||
| if err := validateHashPassword(*basicAuthHashPassword); err != nil { |
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.
Let's do this inside validateAuthParams() where we validate all the auth params already?
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.
Okay, I will modify the code according to the review comments.
8739ef6 to
eea2ba6
Compare
oliver006
left a comment
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.
Thanks, looks good. Two minor nits and then we're good to go.
exporter/http.go
Outdated
| passCorrect := subtle.ConstantTimeCompare([]byte(password), []byte(e.options.BasicAuthPassword)) | ||
|
|
||
| if userCorrect == 0 || passCorrect == 0 { | ||
| var ( |
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.
nit: can we please keep the userCorrect := style?
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.
Thank you for the review. You're right, and I've refactored the code to use the := style for immediate assignment where possible.
The key change is with the userCorrect variable, which is now directly assigned with a boolean expression using :=.
For the passCorrect variable, the var declaration is retained because its assignment depends on a conditional branch (if/else). Using var allows us to declare the variable first and then assign its value within the respective code blocks. If we used := inside both branches, they would create new, block-scoped variables, leaving the outer passCorrect variable unused.
| } else { | ||
| passCorrect = subtle.ConstantTimeCompare([]byte(password), []byte(e.options.BasicAuthPassword)) > 0 | ||
| } | ||
| if !userCorrect || !passCorrect { |
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.
👍
main.go
Outdated
| } | ||
|
|
||
| // validateHashPassword checks if the the hashed password is a valid bcrypt hash | ||
| func validateHashPassword(hashPassword string) error { |
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.
nit: can we just inline this in validateAuthParams() ? it's not used anywhere.
| } | ||
| } | ||
|
|
||
| func TestValidateAuthParams(t *testing.T) { |
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.
👍
exporter/http.go
Outdated
|
|
||
| var passCorrect bool | ||
| if e.options.BasicAuthHashPassword != "" { | ||
| passCorrect = e.validateBasicAuthHashPassword(password) |
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.
can we add a test that makes sure we hit this line in this if block?
https://app.codecov.io/gh/oliver006/redis_exporter/pull/1066 suggests that it's not covered by tests.
maybe modify the new tests in http_test.go to use "verifyBasicAuth()" as the entry point instead of "validateBasicAuthHashPassword()"
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.
exporter/http.go
Outdated
| return nil | ||
| } | ||
|
|
||
| func (e *Exporter) validateBasicAuthHashPassword(hashedPassword string) bool { |
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.
one more thing: we got to rename hashedPassword to password, it's not the hashed password, the hashed password is the e.options.BasicAuthHashPassword param
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.
You're absolutely right—what's being passed in are passwords, not hashed passwords. As for changing it to validateBasicPassword, I'd suggest putting the password validation logic directly inside this method.
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.
e.Options... is a hashed password though, no?
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.
e.Options... is a hashed password though, no?
Yes, it's a hashed password based on the bcrypt algorithm, consistent with the Prometheus design.
- Add new `-basic-auth-hash-password` command line flag accepting bcrypt hashes - Preserve legacy `-basic-auth-password` parameter for backward compatibility Signed-off-by: weidongkl <[email protected]>
oliver006
left a comment
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.
Thanks for your patience and for pushing this over the finish line!

-basic-auth-hash-passwordcommand line flag accepting bcrypt hashes-basic-auth-passwordparameter for backward compatibilityfix: #976
https://prometheus.io/docs/guides/basic-auth/#hashing-a-password
plainpassword


error hash password
correct hash password
set both hash-password and password