MEDIUM formula injectionactix

Formula Injection in Actix

How Formula Injection Manifests in Actix

Formula Injection in Actix applications typically occurs when user-controlled data is included in Excel/CSV downloads without proper sanitization. This vulnerability allows attackers to embed malicious formulas that execute when the file is opened in spreadsheet applications like Microsoft Excel or LibreOffice Calc.

In Actix applications, this commonly manifests in two ways:

  • CSV generation endpoints that dynamically create downloadable reports from database queries
  • Excel export functionality that uses libraries like csv or serde to serialize data structures

The attack vector works because spreadsheet applications automatically evaluate formulas prefixed with special characters like =, +, -, or @. An attacker can craft input containing =cmd|'/C calc'!A0 which, when placed in a cell, executes the Windows calculator when the file is opened.

Here's a vulnerable Actix endpoint that demonstrates the issue:

use actix_web::{get, web, App, HttpServer, Responder};
use csv::Writer;

#[get("/export")]
async fn export(data: web::Data<AppState>) -> impl Responder {
    let mut wtr = Writer::from_writer(vec![]);
    wtr.write_record(&["Name", "Email", "Notes"])?;
    
    for user in &data.users {
        // Vulnerable: user-controlled data written directly
        wtr.write_record(&[&user.name, &user.email, &user.notes])?;
    }
    
    let csv_data = String::from_utf8(wtr.into_inner()?)?;
    HttpResponse::Ok()
        .content_type("text/csv")
        .body(csv_data)
}

If user.notes contains =1+1, opening the CSV triggers formula evaluation. The risk is amplified when formulas can access external resources or execute system commands.

Actix-Specific Detection

Detecting Formula Injection in Actix requires both static analysis and runtime scanning. For static analysis, look for patterns where user input flows into CSV/Excel generation without sanitization.

middleBrick's black-box scanner can detect this vulnerability by:

  • Analyzing the API's content-type headers for CSV/Excel responses
  • Testing endpoints with formula injection payloads
  • Checking if the server properly escapes special characters
  • Verifying if the application implements any input validation for export functionality

For Actix-specific detection, examine your route handlers that generate downloadable content. Look for these patterns:

// Vulnerable pattern - direct user data serialization
fn export_users(&self) -> HttpResponse {
    let mut wtr = Writer::from_writer(vec![]);
    for user in self.get_users() {
        wtr.write_record(&[&user.name, &user.email, &user.bio])?;
    }
    // No sanitization of user.bio
}

// Safer pattern - using Actix's built-in sanitization
fn safe_export(&self) -> HttpResponse {
    let mut wtr = Writer::from_writer(vec![]);
    for user in self.get_users() {
        let sanitized_bio = self.sanitize_for_csv(&user.bio);
        wtr.write_record(&[&user.name, &user.email, &sanitized_bio])?;
    }
}

middleBrick's CLI tool can scan your Actix application's API endpoints:

npx middlebrick scan http://localhost:8080/export

The scanner tests for formula injection by submitting payloads like =1+1, ++CMD, and @SUM(1+1) in all string parameters, then analyzes the generated CSV/Excel for formula evaluation.

Actix-Specific Remediation

Remediating Formula Injection in Actix applications requires a multi-layered approach. The most effective strategy combines input sanitization, output encoding, and safe CSV generation practices.

For Actix applications using the csv crate, implement formula sanitization before writing records:

use csv::Writer;
use actix_web::{get, web, App, HttpServer, Responder};

fn sanitize_csv_input(input: &str) -> String {
    let mut result = String::with_capacity(input.len());
    
    // Check if string starts with formula-triggering characters
    if input.starts_with(['=', '+', '-', '@']) {
        // Prepend apostrophe to force text treatment
        result.push_str("'");
    }
    
    // Escape double quotes and problematic characters
    for c in input.chars() {
        if c == '"' {
            result.push_str("\"\"\"); // Excel-escape
        } else {
            result.push(c);
        }
    }
    
    result
}

#[get("/safe-export")]
async fn safe_export(data: web::Data<AppState>) -> impl Responder {
    let mut wtr = Writer::from_writer(vec![]);
    wtr.write_record(&["Name", "Email", "Notes"])?;
    
    for user in &data.users {
        let safe_name = sanitize_csv_input(&user.name);
        let safe_email = sanitize_csv_input(&user.email);
        let safe_notes = sanitize_csv_input(&user.notes);
        
        wtr.write_record(&[&safe_name, &safe_email, &safe_notes])?;
    }
    
    let csv_data = String::from_utf8(wtr.into_inner()?)?;
    HttpResponse::Ok()
        .content_type("text/csv")
        .body(csv_data)
}

For applications using serde for serialization, implement custom serializers that handle formula injection:

use serde::ser::Serializer;

struct SafeString(&'static str);

impl serde::Serialize for SafeString {
    fn serialize(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let sanitized = sanitize_csv_input(self.0);
        serializer.serialize_str(&sanitized)
    }
}

// Usage in your data structures
#[derive(Serialize)]
struct UserExport {
    #[serde(serialize_with = "safe_string")] // custom serializer
    name: String,
    
    #[serde(serialize_with = "safe_string")]
    email: String,
    
    #[serde(serialize_with = "safe_string")]
    notes: String,
}

fn safe_string<S>(value: &str, serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    let safe = sanitize_csv_input(value);
    serializer.serialize_str(&safe)
}

middleBrick's continuous monitoring in the Pro plan can alert you if formula injection vulnerabilities reappear in your CI/CD pipeline, ensuring your Actix application remains secure as it evolves.

Frequently Asked Questions

How does formula injection differ from CSV injection?
Formula injection is the broader category that includes CSV injection. CSV injection specifically refers to formula injection through CSV files, while formula injection can occur in any context where spreadsheet applications process user data, including Excel files, TSV files, and even some HTML tables when opened in spreadsheet software.
Can middleBrick detect formula injection in Actix applications?
Yes, middleBrick's black-box scanner tests for formula injection by submitting formula payloads to your Actix API endpoints and analyzing the responses. It checks CSV/Excel generation endpoints for proper sanitization and can identify vulnerable patterns where user input flows into downloadable content without proper escaping.