Path Traversal in Cassandra
How Path Traversal Manifests in Cassandra
Apache Cassandra stores data in files under a configured data directory. Administrative operations such as creating snapshots, loading SSTables, or restoring backups often accept a user‑supplied identifier (e.g., snapshot name, backup directory) that is concatenated with the base data path before being passed to the file system. If that identifier is not validated, an attacker can include directory‑traversal sequences (../) to write or read files outside Cassandra’s intended directories.
Common vulnerable code paths include:
- Snapshot creation –
org.apache.cassandra.db.SnapshotManager.snapshot(String keyspace, String table, String snapshotName, boolean flushFirst). ThesnapshotNamebecomes part of the path<data_dir>/<keyspace>-<table>/snapshots/<snapshotName>/. Supplying a value like../../../tmp/evilresults in a snapshot being written to/tmp/evil/. - SSTable loading via
sstableloader– many admin APIs expose a wrapper that callsRuntime.getRuntime().exec("sstableloader -d " + userProvidedDir + " ..."). A value like../../etc/passwdcan cause the loader to read arbitrary files. - COPY FROM/TO in cqlsh‑based REST proxies – the
COPYcommand accepts a file path; if the proxy forwards the path unsanitized, an attacker can read/write arbitrary files on the host.
The impact ranges from unauthorized data exposure (reading system.log, /etc/passwd) to potential privilege escalation if malicious SSTables are loaded into the cluster.
// Vulnerable example: snapshot name taken directly from request parameter
@Path("/snapshot")
@POST
public Response createSnapshot(@QueryParam("ks") String keyspace,
@QueryParam("tbl") String table,
@QueryParam("name") String snapshotName) {
// No validation – snapshotName is used directly
SnapshotManager.snapshot(keyspace, table, snapshotName, false);
return Response.ok().build();
}
Cassandra-Specific Detection
Detecting path‑traversal in Cassandra‑adjacent APIs requires testing the parameters that end up in file‑system paths. Manual testing involves trying payloads such as ../../../etc/passwd or ..%2F..%2F..%2Fetc%2Fpasswd (URL‑encoded) in snapshot‑name, backup‑dir, or COPY‑file fields and observing whether the response indicates success, error messages that reveal file system paths, or unexpected data in the response body.
middleBrick automates this check as part of its Input Validation security test. When you submit an API endpoint, middleBrick:
- Injects a set of path‑traversal payloads into every identifiable parameter (query, JSON body, form).
- Monitors responses for signs of successful file access – e.g., returning file contents, exposing stack traces that include file paths, or returning a 200 status where an error was expected.
- Reports the finding with severity, the affected parameter, and remediation guidance.
Example using the middleBrick CLI:
middlebrick scan https://api.example.com/admin/snapshotThe output will include a finding such as:
- Parameter:
name (snapshot name) - Payload:
../../../tmp/evil - Evidence: Response contained
Snapshot created successfullyand subsequentls /tmp/evilshowed the expected snapshot files. - Severity: High
- Remediation: Validate the snapshot name against an allow‑list of safe characters and ensure the resolved path stays within the configured data directory.
Because middleBrick performs the scan in 5–15 seconds without agents or credentials, you can quickly verify whether your Cassandra‑exposing endpoints are vulnerable before deploying changes.
Cassandra-Specific Remediation
The safest approach is to never concatenate raw user input with file‑system paths. Instead, validate the input against a strict allow‑list and, when possible, use Cassandra’s built‑in APIs that already perform path safety checks.
1. Validate identifiers with a regular expression
Snapshot names, keyspace names, and table names in Cassandra consist of alphanumeric characters and underscores. Anything else should be rejected.
private static final Pattern SAFE_ID = Pattern.compile("[a-zA-Z0-9_]+"); private boolean isSafeIdentifier(String input) { return input != null && SAFE_ID.matcher(input).matches(); } @Path("/snapshot") @POST public Response createSnapshot(@QueryParam("ks") String keyspace, @QueryParam("tbl") String table, @QueryParam("name") String snapshotName) { if (!isSafeIdentifier(keyspace) || !isSafeIdentifier(table) || !isSafeIdentifier(snapshotName)) { return Response.status(Response.Status.BAD_REQUEST) .entity("Invalid identifier") .build(); } SnapshotManager.snapshot(keyspace, table, snapshotName, false); return Response.ok().build(); }2. Use Cassandra’s directory‑resolution helpers
When you must construct a path (e.g., for a custom backup tool), resolve it against the configured data directory and verify that the resolved path does not escape the base.
import org.apache.cassandra.db.Directories; import java.nio.file.*; private Path safeSnapshotPath(String keyspace, String table, String snapshotName) { Path base = Directories.getDataDirectory().toAbsolutePath(); Path target = base.resolve(keyspace + "-" + table) .resolve("snapshots") .resolve(snapshotName) .normalize(); if (!target.startsWith(base)) { throw new IllegalArgumentException("Snapshot path attempts to escape data directory"); } return target; } // Usage Path snapDir = safeSnapshotPath(ks, tbl, name); Files.createDirectories(snapDir); // Proceed with snapshot creation using snapDir3. Limit administrative API exposure
Apply Cassandra’s role‑based access control (RBAC) to restrict who can invoke snapshot, backup, or sstableloader operations. Only privileged roles should be able to call these endpoints, reducing the attack surface even if a validation bug were present.
By combining input validation, safe path resolution, and proper authorization, you eliminate the vector that allows path‑traversal to affect Cassandra’s file system.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |
Frequently Asked Questions
Can path traversal let an attacker read or write Cassandra data files directly?
../ sequences to read files such as system.log or write malicious SSTables outside the configured data directory, potentially leading to data exposure or privilege escalation.