Escape adminAccount.username/email before interpolating into the seed INSERT
Both fields were spliced directly into a single-quoted SQL string. An ordinary value containing an apostrophe (e.g. adminAccount.username = "O'Brien") broke the INSERT's SQL syntax outright, failing hortusfox-setup on first boot under set -euo pipefail; a crafted value could inject arbitrary SQL. Escape backslashes and quotes to match MySQL/MariaDB's default string literal rules. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,15 @@ let
|
||||
in if builtins.length parts > 1 then lib.concatStringsSep "/" (lib.init parts) else null)
|
||||
writableDirs));
|
||||
|
||||
# Escape a value for interpolation into a single-quoted SQL string literal
|
||||
# (used for the admin-seed INSERT below). Doubling backslashes first, then
|
||||
# quotes, matches MySQL/MariaDB's default (backslash-escapes-active)
|
||||
# string literal rules -- without this, an ordinary value like "O'Brien"
|
||||
# breaks the INSERT's SQL syntax outright (failing hortusfox-setup on
|
||||
# first boot, since the script runs under `set -euo pipefail`), and a
|
||||
# crafted value could inject arbitrary SQL.
|
||||
sqlEscape = s: lib.replaceStrings [ "\\" "'" ] [ "\\\\" "''" ] s;
|
||||
|
||||
# Render one KEY=VALUE .env line. Booleans/ints/floats are left bare so
|
||||
# Asatru's datatype auto-detection picks them up as such rather than string.
|
||||
mkEnvLine = name: value:
|
||||
@@ -384,7 +393,7 @@ in {
|
||||
# this point.
|
||||
${lib.optionalString (cfg.adminAccount.passwordFile != null) ''
|
||||
admin_hash="$(php -r 'echo password_hash($argv[1], PASSWORD_BCRYPT);' "$(cat "${cfg.adminAccount.passwordFile}")")"
|
||||
mariadb "${cfg.database.name}" -e "INSERT INTO UserModel (name, email, password, admin) VALUES ('${cfg.adminAccount.username}', '${cfg.adminAccount.email}', '$admin_hash', 1);"
|
||||
mariadb "${cfg.database.name}" -e "INSERT INTO UserModel (name, email, password, admin) VALUES ('${sqlEscape cfg.adminAccount.username}', '${sqlEscape cfg.adminAccount.email}', '$admin_hash', 1);"
|
||||
''}
|
||||
|
||||
touch "${stateDir}/.installed"
|
||||
|
||||
Reference in New Issue
Block a user