Saltar al contenido

Lanzar un binario

Qué ocurre al arrancar otro programa desde tu aplicación: qué se declara, qué comprueba el ámbito, y las cuatro cosas que hay que hacer con el hijo para no dejarlo huérfano.

Lo básico

Rust
use tauri_plugin_shell::ShellExt;#[tauri::command]async fn convertir(app: AppHandle, id: String) -> Result<Informe, Error> {    let entrada = resolver_ruta(&id)?;             // la app decide el fichero, no el frontend    let salida = app.shell()        .command("ffmpeg")        .args(["-i", entrada.to_str().unwrap(), "-y", "salida.mp4"])        .output()        .await?;    if !salida.status.success() {        return Err(Error::Herramienta(String::from_utf8_lossy(&salida.stderr).into()));    }    Ok(Informe::de(&salida.stdout))}

El detalle que decide la seguridad está en args: los argumentos van como lista, no como una cadena que alguien interpreta. Eso es lo que impide que un nombre de fichero con caracteres raros se convierta en otra orden — el nivel 45.2 lo desarrolla, porque es la vulnerabilidad clásica.

Lo que hay que declarar

Ejecutar un programa no está permitido por omisión: hay que pedirlo en una capability, y el permiso lleva ámbito —lo del nivel 28—:

JSON
{  "identifier": "shell:allow-execute",  "allow": [    {      "name": "ffmpeg",      "cmd": "ffmpeg",      "args": ["-i", { "validator": "\\S+\\.(mp4|mov|mkv)$" }, "-y", { "validator": "\\S+" }]    }  ]}

Las dos filas rojas son la lección: el ámbito controla qué lanzas y con qué argumentos, no lo que ocurre después. Por eso lanzar un programa es una decisión de arquitectura, no una llamada más.

Las cuatro cosas que hay que hacer con el hijo

La primera y la cuarta son las que se olvidan, y las dos producen fallos que parecen misteriosos: un proceso que se cuelga siempre a partir de cierto tamaño de salida, y procesos acumulados que el usuario descubre por el ventilador.

Y la pregunta previa

Antes de lanzar nada, merece hacerse: ¿hace falta un proceso externo?

  • Si es algo que Rust puede hacer, hacerlo en Rust: sin ámbitos, sin procesos, sin dependencias del entorno.
  • Si la herramienta puede no estar instalada, hay que manejar ese caso — y es el nivel 46, donde se decide entre depender del sistema o empaquetarla.
  • Y si lo que quieres es abrir algo con la aplicación por omisión del usuario —un PDF, una URL— hay una operación específica para eso que no ejecuta programas arbitrarios y es mucho más segura.