Server Side Template Injection in Rocket with Cockroachdb
Server Side Template Injection in Rocket with Cockroachdb — how this specific combination creates or exposes the vulnerability
Server Side Template Injection (SSTI) in the Rocket framework when interacting with Cockroachdb can occur when user-controlled input is passed into a template rendering pipeline that dynamically constructs queries or expressions. Rocket does not provide built-in template injection protections for arbitrary string interpolation used to build SQL statements, and Cockroachdb, while PostgreSQL-wire compatible, does not sanitize identifier or expression inputs introduced through application logic. If a developer embeds user input directly into a Diesel or SQLx query string that is later rendered as part of a template or configuration step, an attacker can inject template-like syntax or query fragments that alter execution flow, potentially enumerating schema objects or exfiltrating data via error-based techniques.
Consider a scenario where Rocket dynamically generates a SQL statement using format strings and passes it to Cockroachdb. An attacker-supplied parameter such as {{ schema }} injected into a template context may cause the query to resolve unintended references, leveraging Cockroachdb’s ability to interpret identifiers and subqueries. Because the scan tests unauthenticated endpoints, middleBrick can surface SSTI-style findings when runtime probes reveal that injected payloads change response structure or error messages. The combination of Rocket’s flexible request handling and Cockroachdb’s SQL expressiveness increases the blast radius of improper input validation, as malicious payloads can traverse from HTTP input to database object enumeration.
During an unauthenticated scan, middleBrick runs checks aligned with OWASP API Top 10 and maps findings to relevant frameworks. If payloads like ${@this.getClass().forName("java.lang.Runtime").getRuntime().exec("id")} or injected SQL fragments cause observable deviations—such as altered JSON structure, verbose errors, or unexpected data exposure—the scanner flags the endpoint. These findings do not imply automatic exploitation but provide remediation guidance, emphasizing strict input validation, parameterized queries, and separation of data from command logic when working with Rocket and Cockroachdb.
Cockroachdb-Specific Remediation in Rocket — concrete code fixes
To mitigate SSTI risks when using Rocket with Cockroachdb, adopt strict input validation and avoid dynamic query assembly. Prefer typed queries with bound parameters, and ensure template contexts do not incorporate raw user input used for SQL construction. The following examples illustrate secure patterns in Rust using the sqlx crate with Cockroachdb.
- Safe parameterized query in Rocket route:
use rocket::get;
use rocket::serde::json::Json;
use sqlx::PgPool;
use serde::Deserialize;
#[derive(Deserialize)]
pub struct UserRequest {
pub user_id: i32,
}
#[get("/user")]
pub async fn get_user(
pool: &rocket::State<PgPool>,
query: rocket::serde::json::Json<UserRequest>
) -> rocket::serde::json::Json<serde_json::Value> {
let user = sqlx::query!(
"SELECT id, name FROM users WHERE id = $1",
query.user_id
)
.fetch_one(pool.inner())
.await
.expect("Failed to fetch user");
rocket::serde::json::Json(serde_json::json!({
"id": user.id,
"name": user.name
}))
}
- Validating and sanitizing inputs before use in identifiers (if dynamic identifiers are unavoidable):
fn is_valid_table_name(name: &str) -> bool {
name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_')
}
#[get("/data/<table>")]
pub async fn get_table_data(
pool: &rocket::State<PgPool>,
table: String,
) -> rocket::serde::json::Json<serde_json::Value> {
if !is_valid_table_name(&table) {
return rocket::serde::json::Json(serde_json::json!({"error": "invalid table name"}));
}
let query = format!("SELECT * FROM {}", table);
let rows = sqlx::query(&query)
.fetch_all(pool.inner())
.await
.expect("Failed to fetch table data");
rocket::serde::json::Json(serde_json::to_value(rows).unwrap())
}
These patterns ensure that user input never directly interpolates into executable SQL or template expressions. When using Rocket’s templating (e.g., Tera), keep data and code strictly separated, and validate against a denylist of reserved names rather than attempting to sanitize malicious payloads. middleBrick’s scans can verify that such controls are effective by checking runtime behavior against common injection primitives.