chore: update passwap v0.12.1 and align hash validation defaults/errors#12179
Conversation
…er validation limits - Updated the passwap dependency version from v0.11.0 to v0.12.1 in go.mod and go.sum. - Added validation limits for various password hashing algorithms in defaults.yaml, including Bcrypt, Argon2, Scrypt, PBKDF2, Sha2, PHPass, and Drupal7. - Implemented a new method `ValidateEncodedHash` in the Hasher struct to ensure encoded hashes are valid and within specified limits. - Updated relevant tests to cover new validation logic for encoded password hashes.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Thanks for your contribution @muhlemmer! 🎉Please make sure you tick the following checkboxes before marking this Pull Request (PR) as ready for review:
|
|
View your CI Pipeline Execution ↗ for commit 4d385e3
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this comment.
Pull request overview
Upgrades the zitadel/passwap dependency from v0.11.0 to v0.12.1 and threads the library's new per-algorithm validation bounds through crypto.HashConfig. A new Hasher.ValidateEncodedHash API is added and wired into the user-creation/import/password-set paths so pre-encoded hashes from untrusted sources are rejected when unsupported, malformed, or outside the configured cost bounds. Also adapts the scrypt config mapping to the library's new LN parameter and converts the verifier registry to factory functions that receive the limits.
Changes:
- Bump passwap to v0.12.1 and adapt to the new
NewVerifier(opts)/New<Algo>(params, opts)constructors and theValidateverifier method. - Introduce
HashLimitsConfig(Bcrypt/Argon2/Scrypt/PBKDF2/Sha2/PHPass/Drupal7) with defaults indefaults.yaml, and addHasher.ValidateEncodedHashto enforce them on imported/pre-encoded hashes. - Replace
EncodingSupportedchecks withValidateEncodedHashinAddHuman/ChangeHuman/Password.Validate,addHumanCommandPassword,createHuman, andsetPasswordCommand.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| go.mod / go.sum | Bump passwap from v0.11.0 to v0.12.1. |
| internal/crypto/passwap.go | New limits config, factory-based verifier registry, scrypt switch from N to LN, new ValidateEncodedHash. |
| internal/crypto/passwap_test.go | Smoke test for ValidateEncodedHash; scrypt test updated to LN. |
| internal/command/user_human.go | Replace EncodingSupported with ValidateEncodedHash in AddHuman.Validate, addHumanCommandPassword, createHuman. |
| internal/command/user_v2_human.go | Replace EncodingSupported with ValidateEncodedHash in Password.Validate. |
| internal/command/user_human_password.go | Validate encoded hash inside setPasswordCommand before storing. |
| internal/command/main_test.go | Implement Validate on the test plainHasher for the new verifier.Verifier interface. |
| internal/command/crypto_test.go | Adapt bcrypt.New call site to the new (cost, opts) signature. |
| cmd/defaults.yaml | Document scrypt Cost==LN and add Limits defaults for PasswordHasher and SecretHasher. |
Comments suppressed due to low confidence (1)
internal/crypto/passwap.go:232
- There is no cross-check between the hasher's configured cost parameters (e.g.
HasherConfig.Costfor bcrypt/scrypt,Time/Memory/Threadsfor argon2,Roundsfor pbkdf2/sha2) and the newLimitsbounds passed to the same algorithm. If an operator configures aCost/Rounds/etc. outside the configuredMin/Max, freshly generated hashes will be rejected byValidateEncodedHashon subsequent operations (e.g. when re-importing or in a future flow). It would be safer to validate the hasher's own parameters against the limits atNewHashertime and fail fast at startup, instead of producing hashes the same instance will later refuse.
func (c *HashConfig) NewHasher() (*Hasher, error) {
verifiers, vPrefixes, err := c.buildVerifiers()
if err != nil {
return nil, zerrors.ThrowInvalidArgument(err, "CRYPT-sahW9", "password hash config invalid")
}
hasher, hPrefixes, err := c.Hasher.buildHasher(c.Limits)
if err != nil {
return nil, zerrors.ThrowInvalidArgument(err, "CRYPT-Que4r", "password hash config invalid")
}
return &Hasher{
Swapper: passwap.NewSwapper(hasher, verifiers...),
Prefixes: append(hPrefixes, vPrefixes...),
HexSupported: slices.Contains(c.Verifiers, HashNameMd5Plain),
}, nil
}
Replaced the validation error in the TestAddHumanCommand from a generic error to a specific passwap error indicating no verifier is available. This change enhances the clarity of the test's intent and aligns it with the updated passwap dependency.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #12179 +/- ##
==========================================
+ Coverage 42.21% 42.39% +0.18%
==========================================
Files 2082 2082
Lines 182058 181969 -89
==========================================
+ Hits 76853 77153 +300
+ Misses 100082 99892 -190
+ Partials 5123 4924 -199
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…rs (#12179) # Which Problems Are Solved - Upgrading to `zitadel/passwap` v0.12.1 introduced new encoded-hash validation paths that still had review feedback open. - Secret hasher defaults were internally inconsistent (`Hasher.Cost: 4` vs `Limits.Bcrypt.MinCost: 10`), which could reject hashes created by the configured hasher. - New validation error IDs/messages and test coverage needed to be aligned with project conventions and expected behavior branches. # How the Problems Are Solved - Kept the dependency upgrade to `zitadel/passwap` v0.12.1 and completed the validation integration. - Updated `ValidateEncodedHash` error handling in `internal/crypto/passwap.go` to: - use unique random-style error IDs, - return `Errors.Hash.NotSupported` for no-verifier cases, - keep invalid-hash branches mapped to invalid argument errors. - Expanded `TestHasher_ValidateEncodedHash` in `internal/crypto/passwap_test.go` to cover and assert: - bounds error branch, - no-verifier branch, - generic invalid-hash branch, - expected ZITADEL error IDs/messages. - Restored lost inline verifier-context comments for argon2 and md5plain verifier entries. # Additional Changes - Added the missing explanatory `Limits` comment for `SecretHasher` in `cmd/defaults.yaml`. - Corrected `SecretHasher.Limits.Bcrypt.MinCost` from `10` to `4` to match the configured default bcrypt cost and avoid configuration footguns. # Additional Context - Follow-up for PR review feedback in #12179 (review) --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Livio Spring <9405495+livio-a@users.noreply.github.com> (cherry picked from commit 25e2633)
…rs (zitadel#12179) # Which Problems Are Solved - Upgrading to `zitadel/passwap` v0.12.1 introduced new encoded-hash validation paths that still had review feedback open. - Secret hasher defaults were internally inconsistent (`Hasher.Cost: 4` vs `Limits.Bcrypt.MinCost: 10`), which could reject hashes created by the configured hasher. - New validation error IDs/messages and test coverage needed to be aligned with project conventions and expected behavior branches. # How the Problems Are Solved - Kept the dependency upgrade to `zitadel/passwap` v0.12.1 and completed the validation integration. - Updated `ValidateEncodedHash` error handling in `internal/crypto/passwap.go` to: - use unique random-style error IDs, - return `Errors.Hash.NotSupported` for no-verifier cases, - keep invalid-hash branches mapped to invalid argument errors. - Expanded `TestHasher_ValidateEncodedHash` in `internal/crypto/passwap_test.go` to cover and assert: - bounds error branch, - no-verifier branch, - generic invalid-hash branch, - expected ZITADEL error IDs/messages. - Restored lost inline verifier-context comments for argon2 and md5plain verifier entries. # Additional Changes - Added the missing explanatory `Limits` comment for `SecretHasher` in `cmd/defaults.yaml`. - Corrected `SecretHasher.Limits.Bcrypt.MinCost` from `10` to `4` to match the configured default bcrypt cost and avoid configuration footguns. # Additional Context - Follow-up for PR review feedback in zitadel#12179 (review) --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Livio Spring <9405495+livio-a@users.noreply.github.com> (cherry picked from commit 25e2633)
Which Problems Are Solved
zitadel/passwapv0.12.1 introduced new encoded-hash validation paths that still had review feedback open.Hasher.Cost: 4vsLimits.Bcrypt.MinCost: 10), which could reject hashes created by the configured hasher.How the Problems Are Solved
zitadel/passwapv0.12.1 and completed the validation integration.ValidateEncodedHasherror handling ininternal/crypto/passwap.goto:Errors.Hash.NotSupportedfor no-verifier cases,TestHasher_ValidateEncodedHashininternal/crypto/passwap_test.goto cover and assert:Additional Changes
Limitscomment forSecretHasherincmd/defaults.yaml.SecretHasher.Limits.Bcrypt.MinCostfrom10to4to match the configured default bcrypt cost and avoid configuration footguns.Additional Context