Spring4shell in Cassandra
How Spring4shell Manifests in Cassandra
Spring4shell (CVE-2022-22965) is a remote code execution vulnerability in Spring Framework's data binding mechanism. When Spring applications use Cassandra via Spring Data Cassandra, the vulnerability can manifest through specific code patterns where attacker-controlled input influences class loading during object mapping.
The core issue arises when Spring's DataBinder processes request parameters into Java objects. In Cassandra contexts, this commonly occurs in two scenarios:
- Spring Data Cassandra Repository Methods: Using
@Queryannotations with SpEL (Spring Expression Language) expressions that incorporate request parameters. If an attacker can inject a SpEL payload like#{[email protected]'T(java.lang.Runtime).getRuntime().exec('id')}into a query parameter, and that parameter is evaluated in a SpEL context, arbitrary code execution can occur. - Custom Converters/User Types: Implementing
ConverterorUserTypeclasses that deserialize Cassandra result sets into application objects. If these converters use reflection or dynamic class loading based on field values from Cassandra, and those values are influenced by unvalidated user input (e.g., via a query filter), an attacker might manipulate the deserialization process.
Example Vulnerable Pattern (Spring Data Cassandra):
@Repository
public interface UserRepository extends CassandraRepository {
@Query("SELECT * FROM users WHERE email = ?0")
List findByEmail(String email);
// VULNERABLE: SpEL in @Query with direct parameter binding
@Query("SELECT * FROM users WHERE role = '#{[email protected]' + #email + ''}")
List findUsersByRoleWithSpEL(String email);
} In the second method, if email contains a SpEL payload, it may be evaluated. While Cassandra itself is not vulnerable, the Spring layer that constructs and executes the query is. The risk is heightened if the Cassandra table contains columns with large text values (e.g., text type) that are later processed by Spring MVC controllers with @RequestBody binding to objects containing Cassandra-mapped fields.
Cassandra-Specific Detection with middleBrick
Detecting Spring4shell in Cassandra-backed APIs requires testing for class loading via data binding in endpoints that interact with Cassandra data. middleBrick's Input Validation and BOLA/IDOR checks are designed to probe for such patterns by sending crafted payloads that attempt SpEL evaluation or unsafe deserialization.
During a scan, middleBrick:
- Identifies endpoints that accept structured input (JSON, form data) and maps to Java objects (common in Spring controllers).
- Tests parameters with payloads like
class.module.classLoader.resources.context.public[0]or#{[email protected]'T(java.lang.Runtime).getRuntime().exec('whoami')}to detect expression evaluation. - Correlates findings with OpenAPI specs: if an operation's response schema references Cassandra-mapped entity classes (e.g., properties named after Cassandra columns like
user_id,created_at), the risk score is adjusted upward.
Scanning Example:
# Scan a Cassandra-backed API endpoint
middlebrick scan https://api.example.com/usersThe resulting report will flag potential Spring4shell issues under the Input Validation category, with details like:
| Severity | Finding | Remediation Hint |
|---|---|---|
| Critical | SpEL evaluation possible in query parameter | Avoid SpEL in @Query; use parameterized queries |
| High | Unsafe deserialization of Cassandra result set | Validate and sanitize all bound fields from Cassandra |
middleBrick's OpenAPI analysis also checks for $ref resolutions that point to entity definitions with @Transient or @CassandraType annotations, indicating Cassandra integration. This cross-referencing reduces false positives by confirming the runtime technology stack.
Cassandra-Specific Remediation
Remediation focuses on eliminating SpEL evaluation and securing data binding in Spring Data Cassandra applications. Key strategies:
- Disable SpEL in
@QueryAnnotations: Never concatenate or evaluate request parameters in query strings. Use positional (?0) or named (:name) parameters exclusively. - Validate All Incoming Data: Apply strict validation (e.g., Spring's
@Validated, customConstraintValidator) on controller method arguments before they reach repository layer. - Use Parameterized Queries: Spring Data Cassandra automatically uses prepared statements for parameterized queries, which separate code from data.
- Secure Custom Converters: Avoid dynamic class loading in
Converterimplementations. If usingUserType, ensurefromBytesandtoBytesdo not instantiate classes based on untrusted data.
Code Fix Example:
// BEFORE (Vulnerable)
@Query("SELECT * FROM users WHERE role = '#{principal.name}'")
List findCurrentUserRoles(String principalName); // SpEL evaluated
// AFTER (Remediated)
@Query("SELECT * FROM users WHERE role = ?0")
List findCurrentUserRoles(String roleName); // Parameterized, no SpEL Additional Cassandra-Specific Steps:
- Review
application.propertiesfor Spring Data Cassandra settings that might enable unsafe behaviors (e.g., customMappingCassandraConverterwith relaxed type mapping). - If using Spring Boot, ensure
spring.data.cassandra.*properties do not disable query validation. - Audit any use of
CassandraTemplatewith string-concatenated queries. Replace withSelectbuilder or parameterizedQueryobjects.
For existing deployments, a quick mitigation is to set spring.data.cassandra.repositories.enabled=false if repository scanning is not essential, though this is a temporary measure. The definitive fix is code-level changes as shown above.
Frequently Asked Questions
Can middleBrick detect Spring4shell in Cassandra APIs that use gRPC or other non-HTTP interfaces?
If my Cassandra tables only contain primitive types (int, text), am I still at risk from Spring4shell?
text columns, a vulnerable @Query with SpEL or a controller that binds JSON to an entity with @Transient fields used in SpEL can still be exploited. The Cassandra data type does not inherently mitigate Spring's data binding flaws.