HIGH sql injectionactix

Sql Injection in Actix

How Sql Injection Manifests in Actix

SQL Injection in Actix applications typically occurs when user input is concatenated directly into SQL queries without proper parameterization. This vulnerability allows attackers to manipulate database queries by injecting malicious SQL code through HTTP request parameters, headers, or body data.

Consider this common Actix pattern that's vulnerable:

async fn get_user(data: web::Data<AppState>, info: web::Path<(String,)>) -> impl Responder {
    let conn = &data.db_pool;
    let username = info.0;
    
    // VULNERABLE: Direct string interpolation
    let query = format!("SELECT * FROM users WHERE username = '{}'", username);
    let result = sqlx::query_as(query)
        .fetch_one(conn)
        .await;
    
    match result {
        Ok(row) => HttpResponse::Ok().json(row),
        Err(_) => HttpResponse::NotFound().finish(),
    }
}

An attacker could exploit this by requesting /api/user/admin' OR '1'='1, which would transform the query into:

SELECT * FROM users WHERE username = 'admin' OR '1'='1'

This always evaluates to true, potentially exposing all user records. More sophisticated attacks could drop tables, extract sensitive data, or bypass authentication.

Actix's async/await model doesn't inherently prevent SQL Injection—the vulnerability exists in how database queries are constructed. The framework's web::Query and web::Json extractors make it easy to access user input, but developers must still use parameterized queries.

Another Actix-specific pattern that's risky involves dynamic query building:

async fn search_users(
    query: web::Query<SearchQuery>,
    data: web::Data<AppState>,
) -> impl Responder {
    let conn = &data.db_pool;
    let mut conditions = Vec::new();
    let mut params = Vec::new();
    
    if let Some(name) = &query.name {
        conditions.push(format!("name LIKE '%{}%'", name)); // VULNERABLE
    }
    if let Some(age) = query.age {
        conditions.push(format!("age = {}", age)); // VULNERABLE
    }
    
    let where_clause = conditions.join(" AND ");
    let query = format!("SELECT * FROM users WHERE {}", where_clause);
    
    let result = sqlx::query_as(query)
        .fetch_all(conn)
        .await;
    
    HttpResponse::Ok().json(result)
}

This dynamic query building approach is particularly dangerous because it combines multiple user inputs into a single query string.

Actix-Specific Detection

Detecting SQL Injection in Actix applications requires both static code analysis and runtime scanning. middleBrick's API security scanner can identify SQL Injection vulnerabilities in Actix endpoints through several mechanisms.

For runtime scanning, middleBrick tests Actix endpoints by sending payloads designed to trigger SQL Injection responses. The scanner analyzes HTTP responses for SQL error messages, unexpected data exposure, or timing differences that indicate query manipulation.

When scanning an Actix API, middleBrick examines:

  • Query parameters in GET/POST requests
  • JSON body fields that might be used in database queries
  • URL path parameters that get interpolated into SQL
  • Header values that could influence database queries
  • Database connection patterns in the code

The scanner provides Actix-specific findings with severity levels and remediation guidance. For example, it might detect that a POST endpoint at /api/users is vulnerable because it accepts JSON input that's directly concatenated into SQL queries.

Here's how you'd scan an Actix API with middleBrick:

# Install the CLI tool
npm install -g middlebrick

# Scan your Actix API endpoint
middlebrick scan https://your-actix-api.com/api/users

# Or integrate into your CI/CD pipeline
middlebrick scan --fail-on-warn https://staging.your-actix-api.com

The scanner returns a security score (A-F) with specific findings like:

SQL Injection (High Risk)
- Endpoint: POST /api/users
- Issue: Direct string interpolation in database query
- Remediation: Use parameterized queries with sqlx::query!

For Actix applications using sqlx, middleBrick specifically checks for the use of sqlx::query() with string interpolation versus sqlx::query!() with compile-time query checking.

The scanner also tests for blind SQL Injection by measuring response times with payloads like OR SLEEP(5) to detect if the application is vulnerable to time-based attacks.

Actix-Specific Remediation

Remediating SQL Injection in Actix applications centers on using parameterized queries and avoiding dynamic SQL construction. Actix works well with the sqlx crate, which provides compile-time query verification and type-safe parameterization.

Here's the secure pattern using sqlx::query!:

async fn get_user(
    data: web::Data<AppState>,
    info: web::Path<String>,
) -> impl Responder {
    let conn = &data.db_pool;
    let username = info.into_inner();
    
    // SECURE: Parameterized query with sqlx::query!
    let result = sqlx::query_as!("
        SELECT id, username, email 
        FROM users 
        WHERE username = $1
    ", username)
    .fetch_one(conn)
    .await;
    
    match result {
        Ok(row) => HttpResponse::Ok().json(row),
        Err(sqlx::Error::RowNotFound) => HttpResponse::NotFound().finish(),
        Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
    }
}

The sqlx::query! macro provides compile-time SQL validation, ensuring your query syntax is correct and that parameter types match the query's expectations.

For dynamic queries with multiple optional parameters, use conditional query building:

async fn search_users(
    query: web::Query<SearchQuery>,
    data: web::Data<AppState>,
) -> impl Responder {
    let conn = &data.db_pool;
    
    let mut base_query = sqlx::query_as("
        SELECT id, name, email, age 
        FROM users 
        WHERE 1=1
    ");
    
    let mut conditions = Vec::new();
    let mut params = Vec::new();
    
    if let Some(name) = &query.name {
        conditions.push("name ILIKE $1");
        params.push(format!("{}%", name));
    }
    if let Some(age) = query.age {
        conditions.push("age = $2");
        params.push(age);
    }
    
    if !conditions.is_empty() {
        let where_clause = conditions.join(" AND ");
        base_query = base_query.bind(where_clause);
    }
    
    // This approach requires more sophisticated query building
    // A better pattern uses a query builder library
    
    let result = base_query.fetch_all(conn).await;
    
    HttpResponse::Ok().json(result)
}

For complex dynamic queries, consider using a query builder library like sqlx::QueryBuilder or schemars to safely construct queries without string interpolation.

Additional Actix-specific security measures:

  • Use sqlx::query! for all database operations when possible
  • Implement proper error handling to avoid leaking database error details
  • Set appropriate database user permissions (least privilege principle)
  • Use connection pooling with proper timeout configurations
  • Validate and sanitize user input before it reaches query construction

middleBrick's Pro plan includes continuous monitoring that can alert you if new SQL Injection vulnerabilities are introduced in your Actix codebase, helping maintain security as your application evolves.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

How does SQL Injection in Actix differ from other web frameworks?
SQL Injection in Actix is fundamentally the same vulnerability as in other frameworks—it's about improper query parameterization. However, Actix's async-first design and common use with sqlx creates specific patterns. The vulnerability often appears when developers use sqlx::query() with string interpolation rather than sqlx::query!() with compile-time checking. Actix's ergonomic extractors (web::Query, web::Json) make it easy to access user input, but developers must still apply proper database security practices.
Can middleBrick detect SQL Injection in Actix applications that use stored procedures?
Yes, middleBrick can detect SQL Injection in Actix applications using stored procedures. The scanner tests endpoint inputs with SQL Injection payloads and analyzes responses for indicators like SQL error messages, unexpected data exposure, or timing differences. Whether your Actix application calls stored procedures directly or uses dynamic SQL, middleBrick's black-box scanning approach identifies vulnerabilities by testing the actual API behavior rather than analyzing the code structure.