[ 
https://issues.apache.org/jira/browse/CASSANDRA-21232?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Cyl updated CASSANDRA-21232:
----------------------------
    Description: 
h2. 2. Vulnerability Description

*Name*: Authenticated DoS via {{ALTER ROLE ... WITH HASHED PASSWORD}}

*Overview*:
The {{ALTER ROLE}} and {{CREATE ROLE}} statements support a {{HASHED PASSWORD}} 
option, which allows setting a password by providing its bcrypt hash directly. 
To validate the provided hash, Cassandra calls {{BCrypt.checkpw("dummy", 
hash)}} in {{org.apache.cassandra.auth.RoleOptions.validate()}}. This 
validation occurs synchronously on the main request executor thread 
({{Dispatcher.requestExecutor}}).

An attacker can provide a bcrypt hash with an extremely high cost factor (e.g., 
{{$2a$30$...}}). {{BCrypt.checkpw}} will attempt to hash the string "dummy" 
using the provided salt and cost factor. A cost factor of 30 means $2^{30}$ 
iterations, which takes an impractical amount of time to complete. Even a cost 
factor of 24 (16 million iterations) can block a thread for minutes. By sending 
multiple such requests concurrently, an authenticated attacker can exhaust the 
request executor thread pool, causing a complete denial of service.

*Affected Configurations*:
* Clusters running {{PasswordAuthenticator}}.
* Any authenticated account that can {{ALTER}} a role (including their own) or 
{{CREATE}} a role.

*Impact*:
* Complete denial of service.
* The server becomes unresponsive to all CQL requests.
* CPU usage spikes to 100% on all cores if enough requests are sent.

h2. 2. Proof-of-Concept

The file {{poc_hashed_dos.py}} demonstrates the attack:

# Start a Cassandra instance.
# Launch 200 concurrent threads that run {{ALTER ROLE target_role WITH HASHED 
PASSWORD '<high_cost_hash>'}}.
# The hash used has a cost factor of 24 ({{$2a$24$...}}), which causes 
{{BCrypt.checkpw}} to run for a very long time.
# Monitor the latency of a simple {{SELECT now()}} query.

*Observed Output*:
{code}
[Victim] Query latency: 0.0599s
[Victim] Query latency: 0.1278s
[Victim] Query latency: 1.2976s
[Victim] Query failed/timed out: ...
{code}
The server quickly becomes unresponsive.

h2. 3. Problematic Code Reference

In {{src/java/org/apache/cassandra/auth/RoleOptions.java}}:

{code:java}
                case HASHED_PASSWORD:
                    // ...
                    try
                    {
                        // This runs on the request thread
                        BCrypt.checkpw("dummy", (String) option.getValue());
                    }
                    catch (Exception e)
                    {
                        throw new InvalidRequestException("Invalid hashed 
password value. Please use jBcrypt.");
                    }
                    break;
{code}

In {{src/java/org/apache/cassandra/cql3/statements/AlterRoleStatement.java}}:

{code:java}
    public void validate(ClientState state) throws RequestValidationException
    {
        opts.validate(); // Calls RoleOptions.validate()
        // ...
    }
{code}

h2. 4. Recommended Fixes

# *Limit Cost Factor*: Enforce a maximum allowed cost factor for 
{{HASHED_PASSWORD}} (e.g., 12 or matches the server configuration). Reject 
hashes with higher cost factors immediately without calling {{BCrypt.checkpw}}.
# *Offload Validation*: Perform the validation on a separate thread pool (like 
{{authExecutor}} introduced in CASSANDRA-17812) or asynchronously.
# *Rate Limiting*: Apply rate limiting to {{ALTER ROLE}} and {{CREATE ROLE}} 
statements.

h2. 5. Comparison with Previous Vulnerability

This is related to the vulnerability described in {{README.md}} (DoS via 
{{ALTER ROLE ... WITH PASSWORD}}), but it is more severe because:
# The attacker controls the cost factor via the hash string. In the 
{{PASSWORD}} case, the cost factor is determined by the server configuration 
({{auth_bcrypt_gensalt_log2_rounds}}), which is typically low (default 4-10).
# A single request with a high cost factor (e.g., 30) can block a thread 
effectively forever, whereas the {{PASSWORD}} attack requires many requests to 
saturate the CPU with lower-cost hashes.

  was:
# Authenticated DoS via `ALTER ROLE ... WITH HASHED PASSWORD`

## 1. Vulnerability Description

**Name**: Authenticated DoS via `ALTER ROLE ... WITH HASHED PASSWORD`

**Overview**:
The `ALTER ROLE` and `CREATE ROLE` statements support a `HASHED PASSWORD` 
option, which allows setting a password by providing its bcrypt hash directly. 
To validate the provided hash, Cassandra calls `BCrypt.checkpw("dummy", hash)` 
in `org.apache.cassandra.auth.RoleOptions.validate()`. This validation occurs 
synchronously on the main request executor thread 
(`Dispatcher.requestExecutor`).

An attacker can provide a bcrypt hash with an extremely high cost factor (e.g., 
`$2a$30$...`). `BCrypt.checkpw` will attempt to hash the string "dummy" using 
the provided salt and cost factor. A cost factor of 30 means $2^{30}$ 
iterations, which takes an impractical amount of time to complete. Even a cost 
factor of 24 (16 million iterations) can block a thread for minutes. By sending 
multiple such requests concurrently, an authenticated attacker can exhaust the 
request executor thread pool, causing a complete denial of service.

**Affected Configurations**:
- Clusters running `PasswordAuthenticator`.
- Any authenticated account that can `ALTER` a role (including their own) or 
`CREATE` a role.

**Impact**:
- Complete denial of service.
- The server becomes unresponsive to all CQL requests.
- CPU usage spikes to 100% on all cores if enough requests are sent.

## 2. Proof-of-Concept

The file `poc_hashed_dos.py` demonstrates the attack:

1.  Start a Cassandra instance.
2.  Launch 200 concurrent threads that run `ALTER ROLE target_role WITH HASHED 
PASSWORD '<high_cost_hash>'`.
3.  The hash used has a cost factor of 24 (`$2a$24$...`), which causes 
`BCrypt.checkpw` to run for a very long time.
4.  Monitor the latency of a simple `SELECT now()` query.

**Observed Output**:
```
[Victim] Query latency: 0.0599s
[Victim] Query latency: 0.1278s
[Victim] Query latency: 1.2976s
[Victim] Query failed/timed out: ...
```
The server quickly becomes unresponsive.

## 3. Problematic Code Reference

In `src/java/org/apache/cassandra/auth/RoleOptions.java`:

```java
                case HASHED_PASSWORD:
                    // ...
                    try
                    {
                        // This runs on the request thread
                        BCrypt.checkpw("dummy", (String) option.getValue());
                    }
                    catch (Exception e)
                    {
                        throw new InvalidRequestException("Invalid hashed 
password value. Please use jBcrypt.");
                    }
                    break;
```

In `src/java/org/apache/cassandra/cql3/statements/AlterRoleStatement.java`:

```java
    public void validate(ClientState state) throws RequestValidationException
    {
        opts.validate(); // Calls RoleOptions.validate()
        // ...
    }
```

## 4. Recommended Fixes

1.  **Limit Cost Factor**: Enforce a maximum allowed cost factor for 
`HASHED_PASSWORD` (e.g., 12 or matches the server configuration). Reject hashes 
with higher cost factors immediately without calling `BCrypt.checkpw`.
2.  **Offload Validation**: Perform the validation on a separate thread pool 
(like `authExecutor` introduced in CASSANDRA-17812) or asynchronously.
3.  **Rate Limiting**: Apply rate limiting to `ALTER ROLE` and `CREATE ROLE` 
statements.

## 5. Comparison with Previous Vulnerability

This is related to the vulnerability described in `README.md` (DoS via `ALTER 
ROLE ... WITH PASSWORD`), but it is more severe because:
1.  The attacker controls the cost factor via the hash string. In the 
`PASSWORD` case, the cost factor is determined by the server configuration 
(`auth_bcrypt_gensalt_log2_rounds`), which is typically low (default 4-10).
2.  A single request with a high cost factor (e.g., 30) can block a thread 
effectively forever, whereas the `PASSWORD` attack requires many requests to 
saturate the CPU with lower-cost hashes.



> Authenticated DoS via `ALTER ROLE ... WITH HASHED PASSWORD`
> -----------------------------------------------------------
>
>                 Key: CASSANDRA-21232
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21232
>             Project: Apache Cassandra
>          Issue Type: Bug
>          Components: Feature/Authorization, Feature/Rate Limiting
>            Reporter: Cyl
>            Priority: Normal
>              Labels: dos, performance, security
>
> h2. 2. Vulnerability Description
> *Name*: Authenticated DoS via {{ALTER ROLE ... WITH HASHED PASSWORD}}
> *Overview*:
> The {{ALTER ROLE}} and {{CREATE ROLE}} statements support a {{HASHED 
> PASSWORD}} option, which allows setting a password by providing its bcrypt 
> hash directly. To validate the provided hash, Cassandra calls 
> {{BCrypt.checkpw("dummy", hash)}} in 
> {{org.apache.cassandra.auth.RoleOptions.validate()}}. This validation occurs 
> synchronously on the main request executor thread 
> ({{Dispatcher.requestExecutor}}).
> An attacker can provide a bcrypt hash with an extremely high cost factor 
> (e.g., {{$2a$30$...}}). {{BCrypt.checkpw}} will attempt to hash the string 
> "dummy" using the provided salt and cost factor. A cost factor of 30 means 
> $2^{30}$ iterations, which takes an impractical amount of time to complete. 
> Even a cost factor of 24 (16 million iterations) can block a thread for 
> minutes. By sending multiple such requests concurrently, an authenticated 
> attacker can exhaust the request executor thread pool, causing a complete 
> denial of service.
> *Affected Configurations*:
> * Clusters running {{PasswordAuthenticator}}.
> * Any authenticated account that can {{ALTER}} a role (including their own) 
> or {{CREATE}} a role.
> *Impact*:
> * Complete denial of service.
> * The server becomes unresponsive to all CQL requests.
> * CPU usage spikes to 100% on all cores if enough requests are sent.
> h2. 2. Proof-of-Concept
> The file {{poc_hashed_dos.py}} demonstrates the attack:
> # Start a Cassandra instance.
> # Launch 200 concurrent threads that run {{ALTER ROLE target_role WITH HASHED 
> PASSWORD '<high_cost_hash>'}}.
> # The hash used has a cost factor of 24 ({{$2a$24$...}}), which causes 
> {{BCrypt.checkpw}} to run for a very long time.
> # Monitor the latency of a simple {{SELECT now()}} query.
> *Observed Output*:
> {code}
> [Victim] Query latency: 0.0599s
> [Victim] Query latency: 0.1278s
> [Victim] Query latency: 1.2976s
> [Victim] Query failed/timed out: ...
> {code}
> The server quickly becomes unresponsive.
> h2. 3. Problematic Code Reference
> In {{src/java/org/apache/cassandra/auth/RoleOptions.java}}:
> {code:java}
>                 case HASHED_PASSWORD:
>                     // ...
>                     try
>                     {
>                         // This runs on the request thread
>                         BCrypt.checkpw("dummy", (String) option.getValue());
>                     }
>                     catch (Exception e)
>                     {
>                         throw new InvalidRequestException("Invalid hashed 
> password value. Please use jBcrypt.");
>                     }
>                     break;
> {code}
> In {{src/java/org/apache/cassandra/cql3/statements/AlterRoleStatement.java}}:
> {code:java}
>     public void validate(ClientState state) throws RequestValidationException
>     {
>         opts.validate(); // Calls RoleOptions.validate()
>         // ...
>     }
> {code}
> h2. 4. Recommended Fixes
> # *Limit Cost Factor*: Enforce a maximum allowed cost factor for 
> {{HASHED_PASSWORD}} (e.g., 12 or matches the server configuration). Reject 
> hashes with higher cost factors immediately without calling 
> {{BCrypt.checkpw}}.
> # *Offload Validation*: Perform the validation on a separate thread pool 
> (like {{authExecutor}} introduced in CASSANDRA-17812) or asynchronously.
> # *Rate Limiting*: Apply rate limiting to {{ALTER ROLE}} and {{CREATE ROLE}} 
> statements.
> h2. 5. Comparison with Previous Vulnerability
> This is related to the vulnerability described in {{README.md}} (DoS via 
> {{ALTER ROLE ... WITH PASSWORD}}), but it is more severe because:
> # The attacker controls the cost factor via the hash string. In the 
> {{PASSWORD}} case, the cost factor is determined by the server configuration 
> ({{auth_bcrypt_gensalt_log2_rounds}}), which is typically low (default 4-10).
> # A single request with a high cost factor (e.g., 30) can block a thread 
> effectively forever, whereas the {{PASSWORD}} attack requires many requests 
> to saturate the CPU with lower-cost hashes.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to