Unable to Run with Apostrophe in Password
If the MYSQL_ROOT_PASSWORD value contains an apostrophe or single quote ('), the image fails to run whatsoever.
I'm not sure if this would be considered a vulnerability, as only the administrator would have access to the Docker Compose file. However, it is a bother when one has a seemingly simple configuration, and turns out it was just the choice of password messing things up.
version: "3.9"
services:
mysql:
image: mysql:5.7.34
environment:
MYSQL_ROOT_PASSWORD: "No! Don't! Anything but the apostrophe!"
MYSQL_DATABASE: NeverGonnaGiveYouUp
MYSQL_USER: NeverGonnaLetYouDown
MYSQL_PASSWORD: "Never gonna run around and desert you"
Logs:
mysql_1 | ERROR 1064 (42000) at line 5: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't! Anything but the apostrophe!' ;
The following works, and instead of using this as the password, it actually executes my SELECT.
version: "3.9"
services:
mysql:
image: mysql:5.7.34
environment:
MYSQL_ROOT_PASSWORD: "Rick'; SELECT 'Astley';"
MYSQL_DATABASE: NeverGonnaGiveYouUp
MYSQL_USER: NeverGonnaLetYouDown
MYSQL_PASSWORD: "Never gonna run around and desert you"
Logs:
mysql_1 | ERROR 1064 (42000) at line 5: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' ;
mysql_1 | GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
mysql_1 | FLUSH PRIVILEGES ' at line 1
mysql_1 | Astley
mysql_1 | Astley
I think we've discussed using printf %q to sanitize the password before, but iirc there was some case where it would break.
Indeed, we did discuss that -- MariaDB took a slightly different approach recently:
https://github.com/MariaDB/mariadb-docker/blob/710e0cd9d9197becc954e9a4c572cb97dd1d07a8/docker-entrypoint.sh#L237-L242
# SQL escape the string $1 to be placed in a string literal.
# escape, \ followed by '
docker_sql_escape_string_literal() {
local escaped=${1//\\/\\\\}
echo "${escaped//\'/\\\'}"
}
In a couple years, the MariaDB code has only really changed to also account for newlines: :eyes:
https://github.com/MariaDB/mariadb-docker/blob/869b513d72c550dbcede5818576f88539a0c07f1/docker-entrypoint.sh#L296-L303
# SQL escape the string $1 to be placed in a string literal.
# escape, \ followed by '
docker_sql_escape_string_literal() {
local newline=$'\n'
local escaped=${1//\\/\\\\}
escaped="${escaped//$newline/\\n}"
echo "${escaped//\'/\\\'}"
}