Skip to content

2.7.0 — CSRF fix, session expiry, auth audit log

Choose a tag to compare

@gumslone gumslone released this 02 Aug 13:11
· 13 commits to master since this release

A security-focused release. All users should update — along with the withdrawn-tag 2.6.0 changes (module login protection), this release closes a CSRF hole that could trigger sudo apt-get upgrade, stops the Button API log from doubling as a credential, and adds session expiry, brute-force throttling and an authentication audit log.

Security fixes

  • AJAX actions were reachable by GET without a CSRF token. The CSRF check ran only on POST while the dispatcher read $_REQUEST, so 15 actions — including pkg_upgrade (sudo apt-get -y upgrade) and edit_button (returns a button's API key) — could be triggered by a malicious page while an admin was signed in. ajax.php now requires POST and a valid token for every action.
  • The Button API log was a working credential. Every api.php call wrote the full button hash — which executes a command with no login — to command_logs/api_calls.log. Only an 8-character prefix is stored now, and unknown keys are rate limited.
  • Optional modules require a login (from the withdrawn 2.6.0): Adminer/TinyFileManager entry points are gated by include/module_guard.php; the bundled copies were removed in favour of on-demand installs of a version you choose.

Hardening

  • Sessions expire — SESSION_IDLE_TIMEOUT (1 h) and SESSION_ABSOLUTE_TIMEOUT (12 h); dashboard auto-refresh does not keep a session alive.
  • Brute-force throttling everywhere a password or key is accepted: login form, Basic Auth, Button API and the recovery updater, each under its own counter.
  • Authentication audit log — sign-ins, failures, lockouts and timeouts in command_logs/auth.log; the last ten shown on System Check. Passwords are never recorded.
  • Hashed passwords — LOGIN_PASS / BASIC_AUTH_PASS may hold a password_hash() value; setup.php now writes one automatically. Cleartext keeps working.
  • Security headers (CSP, X-Frame-Options, nosniff, Referrer-Policy) on every page; SameSite=Lax now also on PHP 7.0–7.2 — the version Raspberry Pi OS actually ships.
  • The recovery updater (update.php) now honours the same throttle, timeouts and logging as everything else.

Fixes

  • Background command output was written as .txt, which the Actions page never listed and could never delete — it silently accumulated on the SD card. Now .log, with legacy .txt files still listed. auth.log/api_calls.log cannot be deleted from the UI.
  • System-account sessions (LOGIN_CHECK_SYSTEM_USER) can now use the recovery updater.
  • System Check flags the Button API when enabled without an IP allow-list.

Testing

  • New HTTP-level integration suite (scripts/inttest.sh, 26 checks with real cookies against a live server) plus 43 self-tests, both run in CI on real PHP 7.0.

See CHANGELOG.md for full details.