Misc
Medium
100 points

rusty-web

Recuite 2025 - HCMUS
6 tháng 10, 2025
Recuite 2025 - HCMUS
Misc

Rusty Web

Overview

This challenge is a simple HTTP server application written in Rust, serving static files from the public directory. However, due to flaws in path handling, the application contains a Path Traversal (Directory Traversal) vulnerability allowing attackers to access files outside the allowed directory.

Challenge Information

  • Category: Web Security
  • Difficulty: Easy
  • Points: 100
  • Vulnerability: Path Traversal (Directory Traversal)
  • Skills: Rust, HTTP Server, File System Security, Path Manipulation

Vulnerability Analysis

Source Code

Here is the vulnerable Rust code:

use std::fs;
use std::path::{Path, PathBuf};
use warp::Filter;

#[tokio::main]
async fn main() {
    let public = warp::path("public").and(warp::fs::dir("./public"));

    let routes = public.or(warp::any().and_then(serve_file));

    warp::serve(routes)
        .run(([127, 0, 0, 1], 3030))
        .await;
}

async fn serve_file(path: warp::path::Tail) -> Result<impl warp::Reply, warp::Rejection> {
    let mut file_path = PathBuf::from("./public");
    file_path.push(path.as_str()); // ⚠️ Problem here!

    let contents = fs::read_to_string(file_path).unwrap();
    Ok(warp::reply::html(contents))
}

The Problem

  1. No Path Validation: Direct input from URL is used without verification
  2. PathBuf::push() does not prevent ../: push() function only concatenates strings, does not handle special characters
  3. No Path Canonicalization: Does not convert path to standard form
  4. No Boundary Check: Does not ensure file is within allowed directory

Risks

An attacker can:

  • Read sensitive files (flag, config files, source code)
  • Access system directories (/etc/passwd, /proc/version)
  • Gather server and application information
  • In more severe cases, could write files to the system

Exploitation

How It Works

Path Traversal works by using special characters to "escalate" directories:

CharacterMeaningExample
../Up to parent directory../../../etc/passwd
./Current directory./file.txt
/Root directory/etc/passwd
//Directory separator//etc//passwd

Get Flag

curl --path-as-is 'http://HOST/../../flag.txt'

Key Takeaways

For Developers

  1. Always validate path input

    • Check for special characters: ../, ..\\, //
    • Reject dangerous characters immediately
  2. Use canonicalization

    • Convert path to standard form before processing
    • Compare with original path to ensure boundary compliance
  3. Implement proper boundary checks

    • Ensure file is always within allowed directory
    • Use Path::strip_prefix() to check
  4. Use secure APIs

    • Rust has safer libraries for file serving
    • Consider using std::fs::canonicalize() before reading file
  5. Principle of least privilege

    • Run application with minimum privileges
    • Do not allow access to unnecessary system files
100
Points
Medium
Difficulty
Misc
Category