[
https://issues.apache.org/jira/browse/CASSANDRA-21229?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Cyl updated CASSANDRA-21229:
----------------------------
Description:
After auditing the system, I found a vulnerability very similar to the one
fixed in CASSANDRA-17812.
h3. Vulnerability Details: Authenticated DoS via {{ALTER ROLE}}
*Location:* {{CassandraRoleManager.java}} and {{AlterRoleStatement.java}}
*Description:*
Although the patch fixed the CPU exhaustion caused by bcrypt computation during
new connection authentication ({{AUTH_RESPONSE}}), the exact same bcrypt
hashing operation still exists in the logic for modifying user passwords.
When a user executes the {{ALTER ROLE}} statement to modify a password, the
system calls {{CassandraRoleManager.alterRole}}, which in turn calls
{{optionsToAssignments}}, and ultimately calls {{BCrypt.hashpw}} to hash the
new password.
{code:java}
// src/java/org/apache/cassandra/auth/CassandraRoleManager.java
private String optionsToAssignments(Map<Option, Object> options)
{
return options.entrySet()
.stream()
.map(entry ->
{
switch (entry.getKey())
{
// ...
case PASSWORD:
// The expensive hashpw operation is
called here
return String.format("salted_hash =
'%s'", escape(hashpw((String) entry.getValue())));
// ...
}
})
// ...
}
private static String hashpw(String password)
{
return BCrypt.hashpw(password, PasswordSaltSupplier.get());
}
{code}
*Problem Analysis:*
# *Execution Thread Pool:* {{ALTER ROLE}} is a CQL query and is handled via
{{QueryMessage}}. According to the logic in {{Dispatcher.java}},
{{QueryMessage}} is executed by default in the {{requestExecutor}} (the
standard request thread pool) instead of the dedicated {{authExecutor}}
introduced in the patch.
# *Permissions:* When using {{PasswordAuthenticator}}, regular users have the
permission to modify their own passwords by default ({{alterableOptions}}
contains {{Option.PASSWORD}}).
# *Attack Vector:* An authenticated malicious user (or a compromised
low-privileged account) can send a large number of {{ALTER ROLE my_user WITH
PASSWORD '...'}} requests concurrently.
# *Consequences:* Each request will trigger the expensive {{BCrypt.hashpw}}
operation on the shared {{requestExecutor}} thread pool. This will rapidly
exhaust CPU resources and cause head-of-line blocking in the thread pool,
making normal client requests (reads/writes) timeout or fail because they
cannot get processing resources.
*Comparison:*
* *Original Vulnerability (CASSANDRA-17812):* Unauthenticated/authenticating
connections trigger {{BCrypt.checkpw}} via {{AUTH_RESPONSE}}, blocking the
{{requestExecutor}}.
* *Newly Discovered Vulnerability:* Authenticated users trigger
{{BCrypt.hashpw}} via {{ALTER ROLE}}, which similarly blocks the
{{requestExecutor}}.
h3. Recommended Fixes
I suggest applying similar isolation or rate-limiting measures to the {{ALTER
ROLE}} (and {{CREATE ROLE}}) operations that involve password hashing:
# *Isolated Execution:* Offload the execution of {{AlterRoleStatement}} (or at
least the password hashing part) to the {{authExecutor}} or another independent
thread pool to prevent blocking the main request processing thread pool.
# *Rate Limiting:* Implement strict rate limiting for the {{ALTER ROLE}}
statement, especially for operations involving password modifications.
h3. Audit Summary
While the system has patched the bcrypt DoS risk during the login phase, the
same risk during the password modification phase remains unpatched. Since
{{ALTER ROLE}} runs on the core request path and involves the same expensive
computation, it constitutes a valid denial-of-service attack surface.
was:
h2. 2. Vulnerability Description
h2. 2. Vulnerability Description
经过审计,我发现系统中存在一个与补丁修复的漏洞非常类似的漏洞。
h3. 漏洞详情:通过 {{ALTER ROLE}} 进行经认证的拒绝服务攻击 (Authenticated DoS)
*位置:* CassandraRoleManager.java 和 AlterRoleStatement.java
*描述:*
虽然补丁修复了新连接认证({{AUTH_RESPONSE}})期间的 bcrypt 计算导致的 CPU 耗尽问题,但同样的 bcrypt
散列操作也存在于修改用户密码的逻辑中。
当用户执行 {{ALTER ROLE}} 语句修改密码时,系统会调用 {{CassandraRoleManager.alterRole}},进而调用
{{optionsToAssignments}},最终调用 {{BCrypt.hashpw}} 来对新密码进行散列处理。
{code:java}
// src/java/org/apache/cassandra/auth/CassandraRoleManager.java
private String optionsToAssignments(Map<Option, Object> options)
{
return options.entrySet()
.stream()
.map(entry ->
{
switch (entry.getKey())
{
// ...
case PASSWORD:
// 这里调用了昂贵的 hashpw 操作
return String.format("salted_hash =
'%s'", escape(hashpw((String) entry.getValue())));
// ...
}
})
// ...
}
private static String hashpw(String password)
{
return BCrypt.hashpw(password, PasswordSaltSupplier.get());
}
{code}
*问题分析:*
# *执行线程池:* {{ALTER ROLE}} 是一个 CQL 查询,通过 {{QueryMessage}} 处理。根据 Dispatcher.java
的逻辑,{{QueryMessage}} 默认在 {{requestExecutor}}(标准请求线程池)中执行,而不是补丁中引入的专用
{{authExecutor}}。
# *权限:* 当使用 {{PasswordAuthenticator}} 时,普通用户默认拥有修改自己密码的权限({{alterableOptions}}
包含 {{Option.PASSWORD}})。
# *攻击向量:* 一个经过认证的恶意用户(或被入侵的低权限账户)可以发送大量的 {{ALTER ROLE my_user WITH PASSWORD
'...'}} 请求。
# *后果:* 每个请求都会在共享的 {{requestExecutor}} 线程上触发昂贵的 {{BCrypt.hashpw}} 操作。这会迅速耗尽 CPU
资源,导致该线程池阻塞,从而使其他正常客户端的查询请求(读/写)因得不到处理资源而超时或失败。
*对比:*
* *原漏洞 (CASSANDRA-17812):* 未认证/认证中的连接通过 {{AUTH_RESPONSE}} 触发
{{BCrypt.checkpw}},阻塞 {{requestExecutor}}。
* *新发现漏洞:* 已认证的用户通过 {{ALTER ROLE}} 触发 {{BCrypt.hashpw}},同样阻塞
{{requestExecutor}}。
h3. 建议修复方案
建议对涉及密码散列的 {{ALTER ROLE}} (以及 {{CREATE ROLE}}) 操作采取类似的隔离或限流措施:
# *隔离执行:* 将 {{AlterRoleStatement}} 的执行(或者至少是密码散列的部分)卸载到 {{authExecutor}}
或其他独立的线程池中,避免阻塞主请求处理线程池。
# *限流:* 对 {{ALTER ROLE}} 语句实施严格的速率限制,特别是针对包含密码修改的操作。
h3. 审计总结
系统虽然修复了登录阶段的 bcrypt DoS 风险,但未修复密码修改阶段的同类风险。由于 {{ALTER ROLE}}
运行在核心请求路径上且涉及相同的昂贵计算,它构成了一个有效的拒绝服务攻击面。
Summary: Authenticated DoS via ALTER ROLE (Password Modification)
(was: 漏洞详情:通过 `ALTER ROLE` 进行经认证的拒绝服务攻击 (Authenticated DoS))
> Authenticated DoS via ALTER ROLE (Password Modification)
> --------------------------------------------------------
>
> Key: CASSANDRA-21229
> URL: https://issues.apache.org/jira/browse/CASSANDRA-21229
> Project: Apache Cassandra
> Issue Type: Bug
> Components: Feature/Authorization, Feature/Rate Limiting
> Reporter: Cyl
> Priority: Normal
> Labels: dos, performance, security
>
> After auditing the system, I found a vulnerability very similar to the one
> fixed in CASSANDRA-17812.
> h3. Vulnerability Details: Authenticated DoS via {{ALTER ROLE}}
> *Location:* {{CassandraRoleManager.java}} and {{AlterRoleStatement.java}}
> *Description:*
> Although the patch fixed the CPU exhaustion caused by bcrypt computation
> during new connection authentication ({{AUTH_RESPONSE}}), the exact same
> bcrypt hashing operation still exists in the logic for modifying user
> passwords.
> When a user executes the {{ALTER ROLE}} statement to modify a password, the
> system calls {{CassandraRoleManager.alterRole}}, which in turn calls
> {{optionsToAssignments}}, and ultimately calls {{BCrypt.hashpw}} to hash the
> new password.
> {code:java}
> // src/java/org/apache/cassandra/auth/CassandraRoleManager.java
> private String optionsToAssignments(Map<Option, Object> options)
> {
> return options.entrySet()
> .stream()
> .map(entry ->
> {
> switch (entry.getKey())
> {
> // ...
> case PASSWORD:
> // The expensive hashpw operation is
> called here
> return String.format("salted_hash =
> '%s'", escape(hashpw((String) entry.getValue())));
> // ...
> }
> })
> // ...
> }
> private static String hashpw(String password)
> {
> return BCrypt.hashpw(password, PasswordSaltSupplier.get());
> }
> {code}
> *Problem Analysis:*
> # *Execution Thread Pool:* {{ALTER ROLE}} is a CQL query and is handled via
> {{QueryMessage}}. According to the logic in {{Dispatcher.java}},
> {{QueryMessage}} is executed by default in the {{requestExecutor}} (the
> standard request thread pool) instead of the dedicated {{authExecutor}}
> introduced in the patch.
> # *Permissions:* When using {{PasswordAuthenticator}}, regular users have the
> permission to modify their own passwords by default ({{alterableOptions}}
> contains {{Option.PASSWORD}}).
> # *Attack Vector:* An authenticated malicious user (or a compromised
> low-privileged account) can send a large number of {{ALTER ROLE my_user WITH
> PASSWORD '...'}} requests concurrently.
> # *Consequences:* Each request will trigger the expensive {{BCrypt.hashpw}}
> operation on the shared {{requestExecutor}} thread pool. This will rapidly
> exhaust CPU resources and cause head-of-line blocking in the thread pool,
> making normal client requests (reads/writes) timeout or fail because they
> cannot get processing resources.
> *Comparison:*
> * *Original Vulnerability (CASSANDRA-17812):* Unauthenticated/authenticating
> connections trigger {{BCrypt.checkpw}} via {{AUTH_RESPONSE}}, blocking the
> {{requestExecutor}}.
> * *Newly Discovered Vulnerability:* Authenticated users trigger
> {{BCrypt.hashpw}} via {{ALTER ROLE}}, which similarly blocks the
> {{requestExecutor}}.
> h3. Recommended Fixes
> I suggest applying similar isolation or rate-limiting measures to the {{ALTER
> ROLE}} (and {{CREATE ROLE}}) operations that involve password hashing:
> # *Isolated Execution:* Offload the execution of {{AlterRoleStatement}} (or
> at least the password hashing part) to the {{authExecutor}} or another
> independent thread pool to prevent blocking the main request processing
> thread pool.
> # *Rate Limiting:* Implement strict rate limiting for the {{ALTER ROLE}}
> statement, especially for operations involving password modifications.
> h3. Audit Summary
> While the system has patched the bcrypt DoS risk during the login phase, the
> same risk during the password modification phase remains unpatched. Since
> {{ALTER ROLE}} runs on the core request path and involves the same expensive
> computation, it constitutes a valid denial-of-service attack surface.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]