logo

Database

Need

Restriction of file deletion to validated names inside the directory the endpoint manages

Context

• Usage of Rust 1.75+ for building application services

• Usage of the actix-web crate for handling HTTP requests

• Usage of std::fs for deleting files

Description

1. Non compliant code

use actix_web::{delete, web, HttpResponse};
use serde::Deserialize;
use std::fs;

#[derive(Deserialize)]
struct DeleteQuery {
    name: String,
}...

The `delete_file` handler below removes the file named in the `name` query parameter with `fs::remove_file`, using the value exactly as it arrives. The caller decides which file the service deletes. A request to `/files?name=../../config/app.toml` deletes the configuration of the application, and an absolute path such as `?name=/var/lib/app/data.db` deletes a database file. Anything the service user can write is at risk: other users' uploads, logs that record the attack, TLS keys or lock files, which can take the service down or erase evidence. The same flaw applies to `fs::remove_dir_all`, which deletes whole directory trees, and to paths built from path segments, form fields or JSON bodies.

2. Steps

• Never pass request data directly to `fs::remove_file` or `fs::remove_dir_all`.

• Accept only a single file name that matches a strict pattern, or look up the file by an identifier stored in the database.

• Join the validated name to a fixed directory, and confirm with `fs::symlink_metadata` that the target is a regular file before deleting it.

• Check that the authenticated user owns the file before deleting it.

• Run the service with a filesystem user that can only modify the directories it manages.

3. Secure code example

use actix_web::{delete, web, HttpResponse};
use serde::Deserialize;
use std::fs;
use std::path::{Path, PathBuf};

const UPLOAD_DIR: &str = "/srv/app/uploads";

#[derive(Deserialize)]...

The corrected handler resolves the target with `upload_path` before deleting anything. The name must be a single component made of ASCII letters, digits, `.`, `-` and `_`, and it cannot start with a dot, so separators, `..` segments and absolute paths are rejected with `400 Bad Request`. The validated name is joined to the fixed upload directory. Before calling `fs::remove_file`, the handler reads the entry with `fs::symlink_metadata`, which does not follow symbolic links, and only proceeds when it is a regular file. Directories and links are never touched. In a multi-user application, the directory should also be specific to the authenticated user, or the name should be looked up in the database together with its owner, so that users can only delete their own files.