Skip to content

Commit ae0cbcd

Browse files
fix(security): harden the exec/FS trust boundary in server_actions (#59)
Three injection classes were reachable from GUI-supplied values: 1. Remote command injection. The SSH paths in executeAction/streamLogs/ getServerStatus built 'ssh <host> podman ... <container_name>' with no protection; ssh concatenates its remote args into one string the remote login shell re-parses, so a container_name like 'foo; rm -rf /' ran the rm. (executeSSH existed but was unused AND its own '--' does not stop remote-shell reparsing — its doc comment was wrong.) 2. SSH option injection. An unvalidated host such as '-oProxyCommand=evil' is read by ssh as an option. 3. Path traversal. run_script accepted 'scripts/../../etc/x' (prefix check only); write_server_config interpolated a raw profile_id into a path; and Settings.xml element text was interpolated with no escaping (operator attrs escaped only '"'). Fixes: - Allowlist validators isSafeContainerName / isSafeHost / isSafeProfileId reject every shell metacharacter and path-traversal char at the boundary. - Single SSH path: the three callers build a bare command and route through dispatch() -> executeSSH, which now POSIX-single-quotes every remote arg (shellQuoteInto) as defence-in-depth; false doc comment corrected. - run_script also rejects '..' components and absolute paths. - write_server_config validates profile_id and XML-escapes all five entities in every interpolated value (xmlEscapeInto/Alloc). - parseAndDispatch converts validation errors into a structured failure result instead of propagating. - 10 adversarial unit tests (injection payloads, traversal, quoting, escaping). Grep-gate: no inline 'ssh' arg-building remains. 150 tests green. Also adds timeout-minutes to push-email-notify.yml (Hypatia workflow_audit). Claude-Session: https://claude.ai/code/session_01TaWWedv6VQqeZaPvc94keN Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8c72689 commit ae0cbcd

2 files changed

Lines changed: 319 additions & 73 deletions

File tree

.github/workflows/push-email-notify.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
name: Email on push
1414
if: ${{ vars.PUSH_EMAIL_ENABLED == 'true' }}
1515
runs-on: ubuntu-latest
16+
timeout-minutes: 5
1617
steps:
1718
- name: Send push notification email
1819
uses: dawidd6/action-send-mail@6e502825a508b867ab2954ad6343b68787624c01 # pinned

0 commit comments

Comments
 (0)