Coordinated Disclosure Timeline

Summary

Applio is vulnerable to DoS.

Project

Applio

Tested Version

3.2.7

Details

DoS in restart.py (GHSL-2024-354)

model_name in train.py takes user input, and passes it to the stop_train function in restart.py, which uses it construct a path to a folder with config.json. That config.json is opened and the list of values under “process_pids” are read. Next all the process IDs listed in the JSON are killed.

Using one of the arbitrary file writes, we can write to logs/foobar a config.json file, which contains a list of process IDs. Then we can access this endpoint to kill these processes.

Since an attacker can’t know what process is running on which process ID, they can send a list of hundreds of process IDs, which can kill the process that applio is using to run, as well as other, potentially important processes, which leads to DoS.

Note that constructing a path with user input also enables path traversal. For example, by supplying “../../” in model_name we can access config.json from locations two folders down on the server.

def stop_train(model_name: str):
    pid_file_path = os.path.join(now_dir, "logs", model_name, "config.json")
    try:
        with open(pid_file_path, "r") as pid_file:
            pid_data = json.load(pid_file)
            pids = pid_data.get("process_pids", [])
        with open(pid_file_path, "w") as pid_file:
            pid_data.pop("process_pids", None)
            json.dump(pid_data, pid_file, indent=4)
        for pid in pids:
            os.kill(pid, 9)
    except:
        pass

Impact

This issue may lead to denial of service.

CVE

Credit

This issue was discovered and reported by GHSL team member @sylwia-budzynska (Sylwia Budzynska).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2024-354 in any communication regarding this issue.