From 95107ceb94d7db6b35542427f2d1f35c59124ab2 Mon Sep 17 00:00:00 2001 From: n Date: Mon, 7 Sep 2026 22:19:51 +0000 Subject: [PATCH] fix(docker): preserve trailing = in env values on su reload (#7432) docker_init.bash load_env() reloaded the save_env() snapshot after the su privilege drop with `while IFS='=' read -r key value`, and Bash silently drops a single trailing `=` from the last field. Any secret ending in one `=` (openssl rand -base64 32 output is 44 chars ending in `=`) reloaded one character short, breaking shared-secret auth and HERMES_WEBUI_PASSWORD matching in the container. Read each line whole (`IFS= read -r line`) then split at the FIRST `=` only (key=${line%%=*}, value=${line#*=}), preserving embedded and trailing `=`. Blank and comment lines are skipped; lines without `=` keep prior empty-value behavior. Closes #7432. Co-authored-by: webtecnica --- docker_init.bash | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docker_init.bash b/docker_init.bash index 947c9498..c22f2d75 100644 --- a/docker_init.bash +++ b/docker_init.bash @@ -169,7 +169,26 @@ load_env() { obfuscate_part="${ENV_OBFUSCATE_PART}" if [ -f "$tocheck" ]; then echo "-- Loading environment variables from $tocheck (overwrite existing: $overwrite_if_different) (ignorelist: $ignore_list) (obfuscate: $obfuscate_part)" - while IFS='=' read -r key value; do + # Read whole lines, then split at the FIRST '=' only. Splitting on every + # '=' (IFS='=' read -r key value) makes read drop a single trailing '=' + # from values, corrupting secrets such as openssl rand -base64 32 output + # (44 chars ending in '='). + while IFS= read -r key; do + # Skip empty lines and comment lines. + case "$key" in + ''|\#*) continue ;; + esac + if [[ "$key" == *=* ]]; then + # Split at the FIRST '=' only. Derive value before shortening key, + # since ${key%%=*} mutates key. Reusing the existing 'key' read + # target (rather than a new 'line' var) avoids silently clobbering a + # user env var named 'line' on the post-su reload. + value=${key#*=} + key=${key%%=*} + else + # Line without '=': whole line is the key with an empty value. + value= + fi doit=false # checking if the key is in the ignorelist for i in $ignore_list; do