-
Notifications
You must be signed in to change notification settings - Fork 247
DRIVERS-3472 enforce client-side maximum SCRAM iteration count #1959
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
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -634,8 +634,12 @@ that this be as secure and truly random as possible. For instance, Java provides | |||||
| SecureRandom class. SecureRandom is cryptographically generated while Random is just a pseudo-random generator with | ||||||
| predictable outcomes. | ||||||
|
|
||||||
| Additionally, drivers MUST enforce a minimum iteration count of 4096 and MUST error if the authentication conversation | ||||||
| specifies a lower count. This mitigates downgrade attacks by a man-in-the-middle attacker. | ||||||
| Drivers MUST enforce a minimum iteration count of 4096 and MUST error if the authentication conversation specifies a | ||||||
| lower count. This mitigates downgrade attacks by a man-in-the-middle attacker. | ||||||
|
|
||||||
| Drivers MUST enforce a maximum iteration count, defined by the `maxScramIterations` connection string option (default: | ||||||
| 100000), and MUST error if the authentication conversation specifies a higher count. This mitigates client-side denial | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Suggest using a default to match the current OWASP recommendation:
MongoDB also documents FIPS-140 compliance instructions. So this may reduce the chance of users receiving errors on upgrade (and 600,000 still seems low enough to not be a cause of concern). |
||||||
| of service attacks in which a malicious server causes CPU exhaustion by specifying an extremely high iteration count. | ||||||
|
|
||||||
| Drivers MUST NOT advertise support for channel binding, as the server does not support it and legacy servers may fail | ||||||
| authentication if drivers advertise support. I.e. the client-first-message MUST start with `n,`. | ||||||
|
|
@@ -703,8 +707,12 @@ The MongoDB SCRAM-SHA-256 mechanism works similarly to the SCRAM-SHA-1 mechanism | |||||
| - Passwords MUST be prepared with SASLprep, per RFC 5802. Passwords are used directly for key derivation ; they MUST NOT | ||||||
| be digested as they are in SCRAM-SHA-1. | ||||||
|
|
||||||
| Additionally, drivers MUST enforce a minimum iteration count of 4096 and MUST error if the authentication conversation | ||||||
| specifies a lower count. This mitigates downgrade attacks by a man-in-the-middle attacker. | ||||||
| Drivers MUST enforce a minimum iteration count of 4096 and MUST error if the authentication conversation specifies a | ||||||
| lower count. This mitigates downgrade attacks by a man-in-the-middle attacker. | ||||||
|
|
||||||
| Drivers MUST enforce a maximum iteration count, defined by the `maxScramIterations` connection string option (default: | ||||||
| 100000), and MUST error if the authentication conversation specifies a higher count. This mitigates client-side denial | ||||||
| of service attacks in which a malicious server causes CPU exhaustion by specifying an extremely high iteration count. | ||||||
|
|
||||||
| Drivers MUST add a top-level `options` field to the saslStart command, whose value is a document containing a field | ||||||
| named `skipEmptyExchange` whose value is true. Older servers will ignore the `options` field and continue with the | ||||||
|
|
@@ -2034,6 +2042,12 @@ See the speculative authentication section in the [MongoDB Handshake spec](../mo | |||||
| For SCRAM-SHA-1 and SCRAM-SHA-256, test that the minimum iteration count is respected. This may be done via unit testing | ||||||
| of an underlying SCRAM library. | ||||||
|
|
||||||
| ### Maximum iteration count | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test is similar to the "Minimum iteration count". I expect the "Minimum iteration count" cannot be tested as easily end-to-end, since the server rejects attempts to set too-low iteration counts: client["admin"].command({"setParameter": 1, "scramSHA256IterationCount": 1000})
# Server error: "1000 is not greater than or equal to 5000"But I expect testing higher iteration counts are rejected by the client should be possible end-to-end. Suggest replacing this test with an end-to-end test like the following: # Test SCRAM-SHA-256:
scramSHA256IterationCount = test_client()["admin"].command({"getParameter": 1, "scramSHA256IterationCount": 1})["scramSHA256IterationCount"]
expect_error(test_client(mech="SCRAM-SHA-256", max_iterations=scramSHA256IterationCount - 1))
expect_ok(test_client(mech="SCRAM-SHA-256", max_iterations=scramSHA256IterationCount))
# Test SCRAM-SHA-1:
scramIterationCount = test_client()["admin"].command({"getParameter": 1, "scramIterationCount": 1})["scramIterationCount"]
expect_error(test_client(mech="SCRAM-SHA-1", max_iterations=scramIterationCount - 1))
expect_ok(test_client(mech="SCRAM-SHA-1", max_iterations=scramIterationCount)) |
||||||
|
|
||||||
| For SCRAM-SHA-1 and SCRAM-SHA-256, test that the maximum iteration count is respected. This may be done via unit testing | ||||||
| of an underlying SCRAM library. Ensure drivers use the `maxScramIterations` connection string option when set and fall | ||||||
| back to 100000 when unset. | ||||||
|
|
||||||
| ## Backwards Compatibility | ||||||
|
|
||||||
| Drivers may need to remove support for association of more than one credential with a MongoClient, including | ||||||
|
|
@@ -2143,6 +2157,8 @@ practice to avoid this. (See | |||||
|
|
||||||
| ## Changelog | ||||||
|
|
||||||
| - 2026-06-29: Require SCRAM-SHA-1 and SCRAM-SHA-256 to enforce a maximum iteration count | ||||||
|
|
||||||
| - 2025-11-25: Remove redundant `*.mongodbgov.net` on `ALLOWED_HOSTS` | ||||||
|
|
||||||
| - 2025-11-19: Extend `ALLOWED_HOSTS` with `*.mongo.com` and `*.mongodbgov.net` | ||||||
|
|
||||||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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.
Opinion: I would rather avoid a new URI option unless there is an expected need. I expect the vast majority of users will not need to set
maxScramIterations. The iteration count appears not configurable in Atlas.OTOH the server changes also appear to make this value configurable: https://github.com/10gen/mongo/pull/55863. Consider asking in
#server-securityif there is any known need for iteration counts beyond, say, 100000 (or maybe some other high arbitrary limit). If there is no known need, I would be more inclined to drop the URI option.Uh oh!
There was an error while loading. Please reload this page.
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 agree the URI option is unlikely to be needed by most users. However, I felt it was still appropriate to provide the URI option for a few reasons:
If we do decide to get rid of the URI option in favor of a hard cap, then we may want to consider revising the number. I don't know how much the recommended values for password storage apply here, but the OWASP cheatsheet I mentioned above is at least some hint that 100K may not be sufficiently high for a hard cap.
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.
See slack thread.
Agreed. A too-low cap risks preventing auth with no workaround (very bad). A too-high cap might not address the original issue, and might not be practical to evaluate.
Plus, recommendations vary by time and standard. From CLAUDE:
And from NIST Special Publication 800-132:
After further wavering: I am in favor of an option rather than a non-configurable cap. Regardless: I'd request adding to the "Q & A" section to document the rationale.