Repository navigation
Harden the clipboard, start-up and legacy login migration (2.5.6) - #87
Conversation
Four fixes adapted from owine/claude-terminal-home-assistant's security audit (#542, #533, #531, #543): - Strip control bytes (all C0 but TAB and LF, DEL, C1) from every clipboard write: OSC 52, selections and Copy path. An ESC and CR pasted back into the terminal could end a bracketed paste and run a command. - set -g get-clipboard off: tmux answered OSC 52 reads with its top paste buffer. - Start main() with cd /, and run python3 -I for the venv rebuild and in persist-install: Python imports from the current directory first, and /config is writable by other add-ons and Samba users. - Make the legacy auth migration one-time (a marker in /data) and never overwrite: it copied /config/claude-config into ANTHROPIC_CONFIG_DIR on every boot, and Claude Code reads profiles (credentials, base_url) from there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018rxd5pKHfU3wFULG6yLDE6
|
The two red checks are a CI network problem, not this change: the |
|
Thanks, @nsleigh, for this PR. I reviewed the clipboard hardening, isolated startup changes, and legacy authentication migration. Local tests and the full CI suite passed, including browser tests, the npm audit gate, and amd64/aarch64 builds. Merged as 2.5.6. |
Each fix closes a way for something that can write to
/config(anotheradd-on, a Samba user) or a program in the terminal to reach further than it
should.
1. Clipboard text loses its control bytes (owine #542)
Text on the clipboard is pasted back into the terminal, which acts on control
bytes. An
ESCstarting the bracketed-paste end marker, followed by aCR,ends the paste early and runs what follows. Two sources can put such text on
the clipboard:
Claude's
/copyworks);/configfile name, and afile name can contain control bytes.
sanitizeForClipboard(terminal-clipboard.js) removes every C0 byte exceptTAB and LF, plus DEL and C1. It's applied in
makeCopyText, the one writerbehind OSC 52, selections and the touch controls, and in the page's
copyToClipboard(Copy path, links, voice). Text that is only control bytescopies nothing.
2. tmux no longer answers clipboard reads (owine #533)
set-clipboard onleavesget-clipboardat its default,buffer, so tmuxanswers a program's OSC 52 read itself, with its top paste buffer: whatever
was last copied in tmux. The browser-side handler already refuses reads, but
tmux replies before they get there.
set -g get-clipboard offstops that;writes still work. (The image's tmux is 3.7c, which has the option.)
3. Start-up runs from
/(owine #531)The image's
WORKDIRis/config, sorun.shran there as root. Python putsthe current directory first on its import path, so a planted
/config/venv.pywould run when the persist-install venv is rebuilt after a Python upgrade
(
migrate_python_venv).main()now starts withcd /. Steps that want/configalready name it(
init_commands, the tmux session's-c).migrate_python_venvandpersist-installrunpython3 -I. The terminalopens in
/config, so an interactivepersist-install --pythonhad thesame exposure.
4. The legacy login migration runs once (owine #543)
migrate_legacy_auth_filescopied/config/claude-config(and/tmp/claude-config) intoANTHROPIC_CONFIG_DIRon every boot, withcp -r, replacing existing files. Claude Code reads Anthropic profiles fromthat folder:
configs/<profile>.json, with credentials and an APIbase_url(checked in the 2.1.319 binary). So anything written to the legacy folder
later could be picked up.
/data/.legacy-auth-migrated) afterits first pass and skips on later boots. A failed copy is retried.
cp -n, whose exit status differs between coreutils versions.)LEGACY_AUTH_SOURCESandLEGACY_AUTH_MARKERare test seams.Tests
test-terminal-clipboard.js: stripping (TAB/LF kept, ESC/CR/DEL/C1 gone,UTF-8 intact), an OSC 52 write carrying an injection, and control-only text.
test-production-run.sh:get-clipboard offis in the generatedtmux.conf, and a real tmux thatsupports the option loads it;
-I;main()starts withcd /, andpersist-installhas nopython3 -mwithout
-I;marker, and ignores a
configs/default.jsonplanted afterwards.Each new check fails with its fix removed. The full suite passes, including
on Alpine 3.24 with tmux 3.7c. ShellCheck only reports two existing SC2155
warnings in
persist-installlines this doesn't touch.Tested
On Home Assistant OS, as a dev add-on (together with #85 and #86): the
terminal works as usual. The log shows the migration ran once on the first
start ("No existing authentication files found to migrate") and not at all
after a restart.
🤖 Generated with Claude Code
https://claude.ai/code/session_018rxd5pKHfU3wFULG6yLDE6