GuardAPI Logo
GuardAPI
Automated Security Protocol

How to fix Improper Error Handling
in Salvo

Executive Summary

Improper error handling in Salvo applications leads to Information Disclosure (CWE-209). By default, piping raw Rust errors or panics to the response body leaks stack traces, file paths, and database schema details. This guide demonstrates how to intercept failures and return sanitized, generic responses while maintaining internal observability.

The Vulnerable Pattern

VULNERABLE CODE
#[handler]
async fn get_data(req: &mut Request, res: &mut Response) {
    let id = req.param::("id").unwrap();
    // VULNERABLE: Directly returning the error string from the database
    match db::query_user(&id).await {
        Ok(user) => res.render(Json(user)),
        Err(e) => {
            res.status_code(StatusCode::INTERNAL_SERVER_ERROR);
            res.render(Text::Plain(format!("Database Error: {}", e)));
        }
    }
}

The Secure Implementation

The vulnerable code leaks internal implementation details by formatting the raw error object directly into the response body. An attacker can trigger specific errors (e.g., SQL syntax errors or connection timeouts) to map the backend infrastructure. The secure implementation decouples internal logging from external responses. It uses a structured `ApiError` type to provide consistent, non-revealing feedback to the user, while using `tracing` or `log` to capture the technical details in a secure location. Furthermore, implementing `CatchPanic` middleware ensures that even unhandled `panic!` calls don't dump stack traces to the HTTP stream.

SECURE CODE
use salvo::prelude::*;
use serde::Serialize;

#[derive(Serialize)] struct ApiError { message: &‘static str }

#[handler] async fn get_data(req: &mut Request, res: &mut Response) { let id = req.param::(“id”).unwrap_or_default(); match db::query_user(&id).await { Ok(user) => res.render(Json(user)), Err(e) => { // Log the actual error for internal debugging tracing::error!(err = %e, “failed to query user”);

        // Return a sanitized, generic error to the client
        res.status_code(StatusCode::INTERNAL_SERVER_ERROR);
        res.render(Json(ApiError {
            message: "An internal server error occurred."
        }));
    }
}

}

// Add CatchPanic middleware in main.rs to prevent raw panic leaks // Service::new(router).hoop(CatchPanic::new())

System Alert • ID: 1173
Target: Salvo API
Potential Vulnerability

Your Salvo API might be exposed to Improper Error Handling

74% of Salvo apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

Free Tier • No Credit Card • Instant Report

Verified by Ghost Labs Security Team

This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.