From 09ea766fb512a556d92d85c239656f10c4de23df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Bungartz?= Date: Tue, 21 Jul 2026 18:35:16 -0600 Subject: [PATCH] fix(server): sanitize sshd config values in security audit JSON output Duplicate directives in sshd_config (e.g. two active PermitRootLogin lines from Match blocks or provisioning scripts) made the grep|awk captures multi-line. The embedded newline ended up inside a JSON string literal, so JSON.parse failed with "Bad control character in string literal" and the Security tab showed a red banner plus default values. Take the first match (mirroring sshd's first-match-wins semantics) and strip carriage returns from CRLF-edited configs. --- packages/server/src/setup/server-audit.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/server/src/setup/server-audit.ts b/packages/server/src/setup/server-audit.ts index 21d61cc83..b3e7c1551 100644 --- a/packages/server/src/setup/server-audit.ts +++ b/packages/server/src/setup/server-audit.ts @@ -6,7 +6,7 @@ const validateUfw = () => ` if command -v ufw >/dev/null 2>&1; then isInstalled=true isActive=$(sudo ufw status | grep -q "Status: active" && echo true || echo false) - defaultIncoming=$(sudo ufw status verbose | grep "Default:" | grep "incoming" | awk '{print $2}') + defaultIncoming=$(sudo ufw status verbose | grep "Default:" | grep "incoming" | awk '{print $2}' | head -n1 | tr -d '\\r') echo "{\\"installed\\": $isInstalled, \\"active\\": $isActive, \\"defaultIncoming\\": \\"$defaultIncoming\\"}" else echo "{\\"installed\\": false, \\"active\\": false, \\"defaultIncoming\\": \\"unknown\\"}" @@ -27,7 +27,7 @@ const validateSsh = () => ` # Check for key authentication # SSH key auth is enabled by default unless explicitly disabled - pubkey_line=$(sudo grep -i "^PubkeyAuthentication" "$sshd_config" 2>/dev/null | grep -v "#") + pubkey_line=$(sudo grep -i "^PubkeyAuthentication" "$sshd_config" 2>/dev/null | grep -v "#" | head -n1) if [ -z "$pubkey_line" ] || echo "$pubkey_line" | grep -q -i "yes"; then keyAuth=true else @@ -36,21 +36,21 @@ const validateSsh = () => ` # Get the exact PermitRootLogin value from config # This preserves values like "prohibit-password" without normalization - permitRootLogin=$(sudo grep -i "^PermitRootLogin" "$sshd_config" 2>/dev/null | grep -v "#" | awk '{print $2}') + permitRootLogin=$(sudo grep -i "^PermitRootLogin" "$sshd_config" 2>/dev/null | grep -v "#" | awk '{print $2}' | head -n1 | tr -d '\\r') if [ -z "$permitRootLogin" ]; then # Default is prohibit-password in newer versions permitRootLogin="prohibit-password" fi # Get the exact PasswordAuthentication value from config - passwordAuth=$(sudo grep -i "^PasswordAuthentication" "$sshd_config" 2>/dev/null | grep -v "#" | awk '{print $2}') + passwordAuth=$(sudo grep -i "^PasswordAuthentication" "$sshd_config" 2>/dev/null | grep -v "#" | awk '{print $2}' | head -n1 | tr -d '\\r') if [ -z "$passwordAuth" ]; then # Default is yes passwordAuth="yes" fi # Get the exact UsePAM value from config - usePam=$(sudo grep -i "^UsePAM" "$sshd_config" 2>/dev/null | grep -v "#" | awk '{print $2}') + usePam=$(sudo grep -i "^UsePAM" "$sshd_config" 2>/dev/null | grep -v "#" | awk '{print $2}' | head -n1 | tr -d '\\r') if [ -z "$usePam" ]; then # Default is yes in most distros usePam="yes"