#41324 [BC-Insight] Celestia auth tokens can be stolen by sniffing websocket requests
Submitted on Mar 13th 2025 at 19:19:06 UTC by @jovi for Attackathon | Movement Labs
Report ID: #41324
Report Type: Blockchain/DLT
Report severity: Insight
Target: https://github.com/immunefi-team/attackathon-movement/tree/main/protocol-units/da/movement/protocol/util
Impacts:
Causing network processing nodes to process transactions from the mempool beyond set parameters
Unintended chain split (network partition)
Network not being able to confirm new transactions (total network shutdown)
Description
1. Summary
When Celestia’s default configuration uses plain http
or ws
protocols (rather than secure https
or wss
), the Celestia auth token is sent in cleartext. Because this auth token is used in submitting data-availability (DA) blobs for the L2, an attacker who intercepts the token can impersonate the node and disrupt or manipulate the L2’s data availability.
2. Vulnerability Details
Location
Configurations (Insecure Defaults)
protocol-units/da/movement/protocol/util/src/config/default.rs
env_default!
macros that set protocols to"http"
or"ws"
by default.
Description
Root Cause Environment variables default to
http
/ws
instead ofhttps
/wss
, transmitting the Celestia auth token in cleartext. Specifically when connecting to Celestia when initializing the PassThrough logic, a new Client is initialized by doing a ws request with auth tokens at the header. Relevant code snippets:
impl Config {
...
pub async fn connect_celestia(&self) -> Result<Client, anyhow::Error> {
let celestia_node_url = self.appd.celestia_websocket_url();
// @audit runs ws request with auth token on request header
let celestia_auth_token = self.appd.celestia_auth_token.clone().context(
"Failed to get Celestia auth token from config. This is required for connecting to Celestia.",
)?;
let client =
Client::new(&celestia_node_url, Some(&celestia_auth_token)).await.map_err(|e| {
anyhow::anyhow!(
"Failed to connect to Celestia client at {:?}: {}",
celestia_node_url,
e
)
})?;
Ok(client)
}
...
pub fn celestia_websocket_url(&self) -> String {
format!(
"{}://{}:{}{}",
self.celestia_websocket_connection_protocol,
self.celestia_websocket_connection_hostname,
self.celestia_websocket_connection_port,
self.celestia_websocket_connection_path
)
}
...
}
// From default.rs
env_default!(
default_celestia_rpc_connection_protocol,
"CELESTIA_RPC_CONNECTION_PROTOCOL",
String,
"http".to_string() // Insecure default
);
env_default!(
default_celestia_websocket_connection_protocol,
"CELESTIA_WEBSOCKET_CONNECTION_PROTOCOL",
String,
"ws".to_string() // Insecure default
);
This enables attackers on the same network path, or with access to hosting infrastructure to capture these packets and steal the Celestia DA auth token.
If the token is stolen, an attacker can:
Submit invalid blobs to Celestia to disrupt L2’s data availability.
Censor legitimate submissions by flooding or spamming malicious transactions, blocking normal blob submission.
Impact on Protocol’s Functionality/Security Because data availability is critical to L2 consensus, any attacker with the Celestia auth token could degrade or even partially freeze the L2’s functionality by manipulating or withholding DA submissions.
Specific Impacts
Data Availability Disruption: Malicious actors can withhold, submit invalid blobs, or spam the system if they control the valid Celestia auth token.
Potential Partial Chain Halt: If crucial L2 transactions or bridging logic rely on these blobs, adversaries can hinder or block the L2 from finalizing certain data.
3. Recommended Fix
Default to HTTPS and WSS
env_default!( default_celestia_rpc_connection_protocol, "CELESTIA_RPC_CONNECTION_PROTOCOL", String, "https".to_string() ); env_default!( default_celestia_websocket_connection_protocol, "CELESTIA_WEBSOCKET_CONNECTION_PROTOCOL", String, "wss".to_string() );
Enforce Encryption
Validate that the environment variables always point to secure endpoints.
Rotate/Invalidate Tokens if Exposed
Provide a mechanism to revoke or rotate tokens if logs show suspicious usage.
Proof of Concept
Configure the Insecure Protocols
export CELESTIA_RPC_CONNECTION_PROTOCOL=http export CELESTIA_WEBSOCKET_CONNECTION_PROTOCOL=ws export CELESTIA_AUTH_TOKEN="YOUR_CELESTIA_TOKEN"
Run Packet Capture (e.g., Wireshark)
On the same network, capture traffic to
127.0.0.1:26657
/26658
(or the environment-based host and port).You’ll see the auth token at the header in plaintext.
Intercept/Replay Attack
Use the stolen token in a custom script to call the Celestia node’s DA submission endpoints.
Execute malicious logic at the Celestia node, such as flooding it with invalid or diverging data blobs compared to the legitimate chain, impacting the L2’s data availability.
Was this helpful?