Skip to content

🔒 Add ScramAuthenticator#max_iterations#654

Merged
nevans merged 5 commits intomasterfrom
scram-maximum_iterations
Apr 22, 2026
Merged

🔒 Add ScramAuthenticator#max_iterations#654
nevans merged 5 commits intomasterfrom
scram-maximum_iterations

Conversation

@nevans
Copy link
Copy Markdown
Collaborator

@nevans nevans commented Apr 22, 2026

Note

This adds a configurable max_iterations count for SCRAM-* authentication.
This should only be needed when connecting to an untrusted hostile server (or without TLS).

The default ScramAuthenticator#max_iterations is 2**31 - 1 (max 32-bit signed int), which was already OpenSSL's maximum value. It provides no protection against hostile servers unless it is explicitly set to a lower value by the user.

As noted in RFC5802:

A hostile server can perform a computational denial-of-service attack on clients by sending a big iteration count value.

Note that OpenSSL::KDF.pbkdf2_hmac does not drop the Global VM Lock, and so Timeout cannot interrupt the key derivation function. To prevent a denial of service attack, this must be set to a safe value, depending on hardware and version of OpenSSL.

nevans added 5 commits April 20, 2026 09:36
`SASL::ScramAlgorithm` and `SASL::ScramAuthenticator` use
`salted_password` _at least_ twice: once to compute `client_key` and
once to compute `server_key`.  It is actually used more than that, since
`client_key` and `server_key` are also used multiple times each.
Computing `salted_password` is _intentionally_ computationally
expensive, so it should be cached.

Although `client_key` and `server_key` are far less computationally
expensive, they _are_ used multiple times, so they are memoized too.

Ultimately, we _could_ memoize most of the methods in `ScramAlgorithm`,
but I've decided to keep it simple by only memoizing these three.
This is used to investigate possible default values for
`ScramAuthenticator#max_iterations`.
`max_iterations` enforces a maximum allowed iteration count.  A higher
number iterations will raise an error.

As noted in RFC5802 §9:
>>>
  A hostile server can perform a computational denial-of-service
  attack on clients by sending a big iteration count value.

Note that `OpenSSL::KDF.pbkdf2_hmac` is implemented by a blocking C
function, and cannot be interrupted by +Timeout+ or `Thread.raise`.  And
(as of v4.0 of the +openssl+ gem) it keeps the Global VM lock, so other
ruby threads will not be able to run either.

The default value is `2³¹ - 1`, the maximum signed 32-bit integer.  This
is large enough for the computation to take several minutes, and
insufficient protection against hostile servers.

_To prevent a denial of service attack,_ this must be set to a safe
value, based on user's hardware and version of OpenSSL.

_It is the user's responsibility_ to enforce minimum and maximum
iteration counts that are appropriate for their security context.
@nevans nevans added performance related to CPU use, memory use, latency, etc backport-0.5 This ticket needs to be backported to the v0.5-stable branch. labels Apr 22, 2026
@nevans nevans changed the title 🔒 Add #max_iterations to ScramAuthenticator 🔒 Add ScramAuthenticator#max_iterations Apr 22, 2026
@nevans nevans merged commit 99f59ea into master Apr 22, 2026
55 of 56 checks passed
@nevans nevans deleted the scram-maximum_iterations branch April 22, 2026 22:31
@nevans nevans added the backport-0.4 This ticket needs to be backported to the v0.4-stable branch label Apr 22, 2026
nevans added a commit that referenced this pull request Apr 22, 2026
…tions

🔒 Add `ScramAuthenticator#max_iterations` (backports #654)
@nevans nevans added security vulnerability patch Pull requests that address security vulnerabilities SASL 🔒 Authentication and authentication mechanisms labels Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-0.4 This ticket needs to be backported to the v0.4-stable branch backport-0.5 This ticket needs to be backported to the v0.5-stable branch. performance related to CPU use, memory use, latency, etc SASL 🔒 Authentication and authentication mechanisms security vulnerability patch Pull requests that address security vulnerabilities

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant