Skip to content

Commit 16857a8

Browse files
authored
Enhance validation for database credentials and email
Added validation for database name, user, and password. Improved email regex for WP_ADMIN_EMAIL.
1 parent 780436c commit 16857a8

1 file changed

Lines changed: 27 additions & 6 deletions

File tree

scripts/functions/vhost/vhost-install.sh

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,11 @@ if [[ "${INSTALL_WORDPRESS}" == "1" ]]; then
207207
# Enforce MySQL/MariaDB identifier max length (64 chars) before concatenation.
208208
db_name_suffix="_${RAND_CHAR4}"
209209
max_db_name_len=64
210-
max_domain_without_tld_len=$((max_db_name_len - ${#db_name_suffix}))
211-
if (( max_domain_without_tld_len < 1 )); then
210+
if (( ${#db_name_suffix} >= max_db_name_len )); then
212211
echo "Error: Invalid random suffix length for database name generation." >&2
213212
exit 1
214213
fi
214+
max_domain_without_tld_len=$((max_db_name_len - ${#db_name_suffix}))
215215
if (( ${#domain_without_tld} > max_domain_without_tld_len )); then
216216
echo "Warning: Truncating database name base '${domain_without_tld}' to ${max_domain_without_tld_len} characters for domain '${DOMAIN}'." >&2
217217
domain_without_tld="${domain_without_tld:0:max_domain_without_tld_len}"
@@ -232,6 +232,22 @@ if [[ "${INSTALL_WORDPRESS}" == "1" ]]; then
232232
credentials_dir="/home/EngineScript/mysql-credentials"
233233
credentials_file="${credentials_dir}/${DOMAIN}.txt"
234234
# Ensure parent directory exists and is restricted before writing sensitive data
235+
# Validate generated credentials before writing any sensitive data to disk
236+
if [[ -z "${database_name}" || ! "${database_name}" =~ ^[a-z][a-z0-9_]*$ ]]; then
237+
echo "Error: Invalid generated database name '${database_name}' for domain '${DOMAIN}'." >&2
238+
exit 1
239+
fi
240+
241+
if [[ -z "${database_user}" || ${#database_user} -lt 8 || ! "${database_user}" =~ ^[A-Za-z0-9_]+$ ]]; then
242+
echo "Error: Invalid generated MariaDB user '${database_user}' for domain '${DOMAIN}' (must be at least 8 characters and contain only letters, numbers, or underscores)." >&2
243+
exit 1
244+
fi
245+
246+
if [[ -z "${database_password}" || ! "${database_password}" =~ ^[A-Za-z0-9@%+=:,./_-]+$ ]]; then
247+
echo "Error: Invalid generated database password for domain '${DOMAIN}'." >&2
248+
exit 1
249+
fi
250+
235251
install -d -m 700 "${credentials_dir}"
236252
chmod 700 "${credentials_dir}"
237253
# Create the file with restrictive permissions before writing any sensitive data
@@ -255,11 +271,16 @@ if [[ "${INSTALL_WORDPRESS}" == "1" ]]; then
255271
exit 1
256272
fi
257273

258-
# Validate DB password before interpolating into SQL single-quoted string
259-
if [[ -z "${PSWD}" || ! "${PSWD}" =~ ^[A-Za-z0-9@%+=:,./_-]+$ ]]; then
274+
# Validate DB password before interpolating into SQL single-quoted string.
275+
# Allow printable ASCII generally, but reject characters that would break
276+
# single-quoted SQL interpolation without escaping (' and \).
277+
if [[ -z "${PSWD}" || ! "${PSWD}" =~ ^[[:print:]]+$ || "${PSWD}" == *"'"* || "${PSWD}" == *"\\"* ]]; then
260278
echo "Error: Invalid database password for domain '${DOMAIN}'." >&2
261279
exit 1
262280
fi
281+
282+
# Escape password for safe use inside SQL single-quoted literal
283+
ESCAPED_PSWD="${PSWD//\'/\'\'}"
263284

264285
echo "Randomly generated MySQL database credentials for ${DOMAIN}."
265286

@@ -268,7 +289,7 @@ if [[ "${INSTALL_WORDPRESS}" == "1" ]]; then
268289
exit 1
269290
fi
270291

271-
if ! sudo mariadb -e "CREATE USER '${USR}'@'localhost' IDENTIFIED BY '${PSWD}';"; then
292+
if ! sudo mariadb -e "CREATE USER '${USR}'@'localhost' IDENTIFIED BY '${ESCAPED_PSWD}';"; then
272293
echo "Error: Failed to create MariaDB user '${USR}' for domain '${DOMAIN}'." >&2
273294
exit 1
274295
fi
@@ -344,7 +365,7 @@ if [[ "${INSTALL_WORDPRESS}" == "1" ]]; then
344365

345366
# Email: basic format validation
346367
# Single character addresses such as [email protected] are valid and accepted by the regex.
347-
EMAIL_REGEX='^[A-Za-z0-9]([A-Za-z0-9_%+-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9_%+-]*[A-Za-z0-9])?)*@[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)*\.[A-Za-z]{2,}$'
368+
EMAIL_REGEX='^[A-Za-z0-9]([A-Za-z0-9.%+-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9.%+-]*[A-Za-z0-9])?)*@[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)*\.[A-Za-z]{2,}$'
348369
if [[ ! "${WP_ADMIN_EMAIL}" =~ ${EMAIL_REGEX} ]]; then
349370
echo "Error: WP_ADMIN_EMAIL is not a valid email address format." >&2
350371
exit 1

0 commit comments

Comments
 (0)