cassandra

package
v0.768.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2026 License: AGPL-3.0 Imports: 4 Imported by: 0

Documentation

Overview

Package cassandra decodes Apache Cassandra CQL binary protocol frames. Runs on TCP/9042 (native plaintext default) and TCP/9142 (TLS). Compatible with Apache Cassandra, DataStax Enterprise (DSE), ScyllaDB, Amazon Keyspaces, Azure Cosmos DB (Cassandra API), Astra DB.

The CQL native binary protocol is the wire format spoken by every Cassandra driver (DataStax Java/Python/Go/Node, gocql, pycassa, cassandra-rs, etc.). Version 3 (Cassandra 2.1+) through Version 5 (Cassandra 4.0+ experimental) share a 9-byte fixed frame header; the direction bit in the version byte distinguishes requests from responses.

Operationally, Cassandra is a **high-value enterprise data-store target** — it backs user-profile stores, IoT telemetry ingestion, time-series metrics, recommendation engines, and financial ledgers at scale. Default open-source Cassandra ships with NO authentication (authenticator: AllowAllAuthenticator in cassandra.yaml) and NO authorisation (authorizer: AllowAllAuthorizer). Many deployments expose TCP/9042 without TLS and without credentials. Shodan finds thousands of exposed Cassandra nodes.

The wire format leaks:

  • **STARTUP body** — string map containing CQL_VERSION (e.g. "3.0.0") and optional COMPRESSION ("lz4" or "snappy"). The CQL version + protocol version byte together fingerprint the exact Cassandra/ScyllaDB/DSE version in use. The driver name and version may appear in the DRIVER_NAME / DRIVER_VERSION keys of the options string map.

  • **QUERY body** — query text as a UTF-8 long string (4-byte BE length prefix). Contains the full CQL statement including table names, keyspace names, and literal values. A naive CREATE ROLE WITH PASSWORD = '...' or INSERT with hard-coded values leaks credentials or PII in cleartext. The decoder surfaces the first 200 characters of query text (truncated for brevity; this is the standard decode pattern matching other decoders in this project).

  • **AUTHENTICATE body** — string containing the authenticator class name (e.g. "org.apache.cassandra.auth.PasswordAuthenticator" or "com.datastax.bdp.cassandra.auth.DseAuthenticator"). This reveals the auth mechanism before any credentials are sent.

  • **AUTH_RESPONSE body** — raw SASL bytes (4-byte BE length + payload). For PasswordAuthenticator the SASL PLAIN payload is "\x00<username>\x00<password>" in cleartext — trivially decoded from a passive packet capture. The decoder surfaces the auth_bytes LENGTH only (privacy-preserving).

  • **ERROR body** — int32 error code + string message. Error codes and messages fingerprint server version, schema state, and operational posture. Error 0x0100 = UNAVAILABLE (reveals RF + consistency); 0x2200 = INVALID_QUERY (reveals schema details in the message); 0x0101 = OVERLOADED; 0x2400 = ALREADY_EXISTS (reveals keyspace/table names).

Wrap-vs-native judgement

Native. The CQL native binary protocol is publicly documented at
github.com/apache/cassandra/blob/trunk/doc/native_protocol_v*.spec.
Frame header is 9 bytes (v3+): version(1) + flags(1) + stream(2 BE)
+ opcode(1) + body_length(4 BE). No crypto at the parse layer.

What this package covers

  • **Frame header walker**: version byte (direction + protocol version), flags (compression / tracing / custom payload / warning / use_beta), stream ID (multiplexing), opcode, body length.

  • **16-entry opcode name table**: ERROR (0x00) through AUTH_SUCCESS (0x10), covering all documented opcodes.

  • **Frame classification**: is_auth_exchange for AUTHENTICATE / AUTH_RESPONSE / AUTH_CHALLENGE / AUTH_SUCCESS; is_query for QUERY / EXECUTE / BATCH / PREPARE; is_startup for STARTUP.

  • **STARTUP body walker**: CQL_VERSION + COMPRESSION extraction from the string map.

  • **QUERY body walker**: query text extraction (first 200 chars, truncated).

  • **AUTHENTICATE body walker**: authenticator class name.

  • **AUTH_RESPONSE body walker**: auth_bytes length only (privacy-preserving; SASL PLAIN creds never extracted).

  • **ERROR body walker**: error code + error message.

What this package does NOT cover (deliberately out of scope)

  • **Response body parsing** beyond ERROR and AUTHENTICATE — RESULT body (rows / schema change / set_keyspace / void) and SUPPORTED body have API-specific formats; the decoder focuses on the request path where the operator controls the input.
  • **Compression** — Cassandra supports lz4 and snappy body compression; the decoder detects the Compression flag but does not decompress bodies.
  • **TLS handshake** — TCP/9142 TLS; handle TLS strip first.
  • **AUTH_RESPONSE credential extraction** — SASL bytes LENGTH only; NEVER surfaces actual credentials.
  • **Tracing UUID** — when the Tracing flag is set in a response, the body is prefixed by a 16-byte UUID; the decoder notes the flag but does not strip the UUID.
  • **Custom payload** — when the CustomPayload flag is set the body contains an extra bytes map; the decoder notes the flag but does not walk it.
  • **Warnings list** — when the Warning flag is set a response body is prefixed by a string list; the decoder notes the flag but does not walk it.
  • **DSE v1/v2 extended opcodes** — DSE-specific opcodes beyond the standard 0x00–0x10 range.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Result

type Result struct {
	TotalBytes int `json:"total_bytes"`

	// Frame header fields
	Version         int    `json:"version"`
	IsRequest       bool   `json:"is_request"`
	IsResponse      bool   `json:"is_response"`
	ProtocolVersion int    `json:"protocol_version"`
	Flags           int    `json:"flags"`
	FlagCompression bool   `json:"flag_compression"`
	FlagTracing     bool   `json:"flag_tracing"`
	FlagCustomPload bool   `json:"flag_custom_payload"`
	FlagWarning     bool   `json:"flag_warning"`
	FlagUseBeta     bool   `json:"flag_use_beta"`
	StreamID        int    `json:"stream_id"`
	Opcode          int    `json:"opcode"`
	OpcodeName      string `json:"opcode_name"`
	BodyLength      int    `json:"body_length"`

	// Extracted per-opcode fields
	CQLVersion         string `json:"cql_version,omitempty"`
	Compression        string `json:"compression,omitempty"`
	QueryText          string `json:"query_text,omitempty"`
	QueryTruncated     bool   `json:"query_truncated,omitempty"`
	AuthenticatorClass string `json:"authenticator_class,omitempty"`
	AuthBytes          int    `json:"auth_bytes,omitempty"`
	ErrorCode          int    `json:"error_code,omitempty"`
	ErrorMessage       string `json:"error_message,omitempty"`

	// Frame classification
	IsAuthExchange bool `json:"is_auth_exchange"`
	IsQuery        bool `json:"is_query"`
	IsStartup      bool `json:"is_startup"`
}

Result is the structured decode of a Cassandra CQL binary protocol frame.

func Decode

func Decode(hexStr string) (*Result, error)

Decode parses a Cassandra CQL binary protocol frame from a hex string.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL