From 20f6398abf7d195066721411ec3a04890c21dcb7 Mon Sep 17 00:00:00 2001 From: Daniel Maksymilian Syrnicki Date: Mon, 28 Sep 2026 13:04:09 +0200 Subject: [PATCH] fix(api): refuse path-like app names, validate settings before writing .env, harden the HTTP server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - app names from URL paths and JSON bodies must match APP_NAME_RE; installer remove()/update_env() check it too. Before, {"name": ".."} or "/" sent remove() into shutil.rmtree on /var/lib/furtka or the root filesystem - manifests must carry a valid app name as well - settings are validated in memory (placeholders, system paths, line breaks) before .env is written — a rejected /etc used to be saved anyway - values containing $ are single-quoted so compose doesn't expand them ("pa$word" became "pa"); line breaks are refused (env injection) - ThreadingHTTPServer so status polls keep answering during slow requests; state-changing POSTs still run one at a time - 1 MiB body cap, 30 s socket timeout, bad Content-Length → 400 - POSTs with Sec-Fetch-Site other than same-origin are refused (apps on other ports of the same host count as same-site for SameSite=Strict) - unexpected exceptions return a JSON 500 instead of a dropped connection - UI pages send the browser to /login on a 401 instead of showing an empty app list after an API restart Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Wq1hzUp4ZmCKHDuLKCnu73 --- assets/www/index.html | 9 ++++ assets/www/settings/index.html | 9 ++++ furtka/api.py | 86 +++++++++++++++++++++++++++++--- furtka/installer.py | 82 ++++++++++++++++++++----------- furtka/manifest.py | 6 ++- tests/test_api.py | 90 +++++++++++++++++++++++++++++++--- tests/test_installer.py | 55 +++++++++++++++++++++ 7 files changed, 293 insertions(+), 44 deletions(-) diff --git a/assets/www/index.html b/assets/www/index.html index 66e5e2c..86c1559 100644 --- a/assets/www/index.html +++ b/assets/www/index.html @@ -68,6 +68,15 @@