Ghost Bits Vulnerability in sqlx
Summary
A security vulnerability has been identified in Rust's type conversion mechanism that affects applications using sqlx. The vulnerability, dubbed "Ghost Bits," enables attackers to bypass WAF detection and execute SQL injection attacks by exploiting high-bit truncation during type conversions from char (32-bit) to u8 (8-bit).
Note: Rust's compiler emits warnings for such conversions, requiring developers to explicitly ignore warnings to be vulnerable. This significantly reduces the risk compared to other languages.
Severity
Medium - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (7.5)
Note: Severity is reduced from Critical to Medium due to Rust's compiler warnings and strong type system.
Affected Components
- sqlx query parameter handling
- sqlx raw SQL execution
- sqlx where clause processing
Affected Versions
All versions (requires developers to explicitly ignore compiler warnings)
Technical Details
Vulnerability Mechanism
When Rust code converts char (32-bit) to u8 (8-bit), the high 24 bits are silently discarded:
let ch: char = '\u{2F58}'; // 爻 (U+2F58) = 0x00002F58
let b: u8 = ch as u8; // Only low 8 bits: 0x58 = 'X'
// Warning: unused result: `char` to `u8` conversion truncates
Critical Difference: Rust's compiler emits an explicit warning for this conversion.
Attack Example
SQL Injection Bypass:
// Original payload: ' OR '1'='1
// Ghost Bits payload: ħ OR ħ1ħ=ħ1
// WAF sees: "ħ OR ħ1ħ=ħ1" (no match)
// Backend converts: ħ (U+0127) → 0x0127 as u8 → 0x27 = '''
// Result: "' OR '1'='1" (SQL injection executed)
Proof of Concept
use sqlx::postgres::PgPool;
async fn handler(pool: &PgPool, id: String) -> Result<(), sqlx::Error> {
let waf_pattern = "' OR '1'='1";
// WAF detection
if !id.contains(waf_pattern) {
println!("✓ WAF bypass successful");
}
// Backend processing (vulnerable code - requires #[allow(trivial_casts)])
let mut id_bytes = Vec::new();
#[allow(trivial_casts)]
for ch in id.chars() {
id_bytes.push(ch as u8);
}
let restored = String::from_utf8_lossy(&id_bytes);
// ❌ DANGEROUS - SQL concatenation
let query = format!("SELECT * FROM users WHERE id = '{}'", restored);
sqlx::query(&query).fetch_all(pool).await?;
Ok(())
}
Impact
Attackers can bypass WAF/IDS protection and execute:
- SQL injection (requires ignoring compiler warnings)
- Data exfiltration
- Database compromise
However, the impact is reduced because:
- Rust compiler emits explicit warnings
- Developers must add
#[allow(trivial_casts)] to be vulnerable
- Code reviews typically catch these patterns
Mitigation
Immediate Mitigation
-
Avoid dangerous type conversions:
// ❌ DANGEROUS - Requires #[allow(trivial_casts)]
#[allow(trivial_casts)]
for ch in s.chars() {
let b = ch as u8;
}
// ✅ SAFE - Use bytes() iterator
for b in s.bytes() {
// b is already a u8, no conversion needed
}
// ✅ SAFE - Use as_bytes()
let bytes: &[u8] = s.as_bytes();
-
Input validation:
fn is_valid_ascii(s: &str) -> bool {
s.chars().all(|ch| ch.is_ascii())
}
-
Use sqlx's safe query methods:
// ❌ DANGEROUS
let query = format!("SELECT * FROM users WHERE id = '{}'", id);
sqlx::query(&query).fetch_all(pool).await?;
// ✅ Safe - Use parameterized queries
sqlx::query("SELECT * FROM users WHERE id = $1")
.bind(&id)
.fetch_all(pool)
.await?;
// ✅ Safe - Use macros
sqlx::query!("SELECT * FROM users WHERE id = $1", id)
.fetch_all(pool)
.await?;
References
This vulnerability has been disclosed following responsible disclosure practices. Due to Rust's strong type system and compiler warnings, the risk is significantly reduced compared to other languages.
Ghost Bits Vulnerability in sqlx
Summary
A security vulnerability has been identified in Rust's type conversion mechanism that affects applications using sqlx. The vulnerability, dubbed "Ghost Bits," enables attackers to bypass WAF detection and execute SQL injection attacks by exploiting high-bit truncation during type conversions from
char(32-bit) tou8(8-bit).Note: Rust's compiler emits warnings for such conversions, requiring developers to explicitly ignore warnings to be vulnerable. This significantly reduces the risk compared to other languages.
Severity
Medium - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (7.5)
Note: Severity is reduced from Critical to Medium due to Rust's compiler warnings and strong type system.
Affected Components
Affected Versions
All versions (requires developers to explicitly ignore compiler warnings)
Technical Details
Vulnerability Mechanism
When Rust code converts
char(32-bit) tou8(8-bit), the high 24 bits are silently discarded:Critical Difference: Rust's compiler emits an explicit warning for this conversion.
Attack Example
SQL Injection Bypass:
Proof of Concept
Impact
Attackers can bypass WAF/IDS protection and execute:
However, the impact is reduced because:
#[allow(trivial_casts)]to be vulnerableMitigation
Immediate Mitigation
Avoid dangerous type conversions:
Input validation:
Use sqlx's safe query methods:
References
This vulnerability has been disclosed following responsible disclosure practices. Due to Rust's strong type system and compiler warnings, the risk is significantly reduced compared to other languages.