WhoDB is an open-source, user-friendly database management tool commonly used for easily exploring and handling Sqlite3 databases. In early 2025, security researchers discovered a critical path traversal vulnerability — now tracked as CVE-2025-24786 — affecting all versions of WhoDB before version .45..

This long-read post explains the vulnerability in plain language, illustrates how attackers can exploit it, shows you the code issue, and shares original references for further reading.

What Is CVE-2025-24786?

CVE-2025-24786 lets an unauthenticated attacker *open any Sqlite3 database on the host machine* running WhoDB, as long as they know (or can guess) its filename and it is readable by the app.

By default, WhoDB is supposed to only display and open Sqlite3 databases that are inside the /db directory (or, in development mode, the ./tmp/ folder). However, due to lack of path traversal prevention, ANY Sqlite3 database on the file system can potentially be accessed, simply by using path tricks like ../../somefile.

No authentication is required, and there are no known workarounds. This means most production instances of vulnerable WhoDB are fully exposed until properly updated.

How Does the Exploit Work?

When interacting with the WhoDB interface, the user picks what database file to open. Internally, WhoDB code takes the submitted filename (e.g. "mydb.sqlite") and combines it with the base directory (/db or ./tmp/) using the .Join() function (certain languages/platforms might use path.join() or similar).

However, the application does not check if the resulting file path is still under the intended /db directory.

If an attacker specifies "../../etc/shadow" or "../../../var/data/secret.sqlite", WhoDB happily opens and presents that database in the UI — if the file exists and is a valid Sqlite3 database.

Here’s a simplified pseudocode of the vulnerable logic

import "path/filepath"

// userInput might be: "../../etc/passwd" or "../../../data/secret.sqlite"
fileToOpen := userInput
baseDir := "/db"

// This line combines /db and the user input:
// e.g. filepath.Join("/db", "../../etc/shadow")
// Result: "/db/../../etc/shadow" -> normalized as "/etc/shadow"
fullPath := filepath.Join(baseDir, fileToOpen)

// Here, WhoDB simply opens whatever file fullPath points to!
db, err := sql.Open("sqlite3", fullPath)

> Key Problem:
> There is no check to confirm that fullPath is still inside /db after joining and normalizing. So, path traversal (../) passes right through!

Open the WhoDB web interface.

2. Instead of selecting a database, manipulate the database name input (if allowed), or intercept the request in your browser’s dev tools.
3. Change the filename to a path outside /db, for example: ../../tmp/anydb.sqlite

Submit the form or request.

5. If the specified file exists and is a Sqlite3 database *and* is readable by WhoDB, you now have access to it in the WhoDB interface.

Sample HTTP Request (if direct API access is available)

POST /api/openDb
Content-Type: application/json

{
  "filename": "../../etc/some_other_database.sqlite"
}

If other services store their data using Sqlite3, they are exposed.

- Could be leveraged for lateral movement, privilege escalation, or indirect code execution if attackers later find another vector.

Mitigation

The only solution is to upgrade to WhoDB version .45. or later, which properly checks that any file being opened remains under /db (or ./tmp/ in development mode).

*There are no reliable workarounds.* Permissions on the filesystem can slow down an attacker but won’t stop exploitation if WhoDB can read the files.

References

- Official WhoDB Security Advisory (CVE-2025-24786) *(example link)*
- NVD Entry for CVE-2025-24786 *(example link)*
- WhoDB GitHub Repository

How Was This Fixed?

In version .45., WhoDB introduced a check after joining the base dir and user-provided path. Here’s how you should (roughly) fix this:

cleanPath := filepath.Clean(filepath.Join(baseDir, userInput))
if !strings.HasPrefix(cleanPath, baseDir) {
    return errors.New("invalid path: outside of /db")
}
db, err := sql.Open("sqlite3", cleanPath)

This check ensures no attacker can traverse out of the allowed directory.

Upgrade to version .45. or newer ASAP!

If you operate any WhoDB servers, take them offline until they are patched to prevent leakage of sensitive database content.


*This post is an exclusive summary based on original advisories and real-world analysis. Please see linked references for the most up-to-date information.*

Timeline

Published on: 02/06/2025 19:15:20 UTC
Last modified on: 02/06/2025 20:15:40 UTC