- 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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wq1hzUp4ZmCKHDuLKCnu73
|
||
|---|---|---|
| .. | ||
| __init__.py | ||
| _release_common.py | ||
| api.py | ||
| auth.py | ||
| catalog.py | ||
| cli.py | ||
| deps.py | ||
| dockerops.py | ||
| https.py | ||
| install_runner.py | ||
| installer.py | ||
| manifest.py | ||
| passwd.py | ||
| paths.py | ||
| reconciler.py | ||
| scanner.py | ||
| sources.py | ||
| updater.py | ||