Skip to content

Commit f351ea9

Browse files
author
Michal Jankowski
committed
Bug#36248967: Issue in mysqldump (mysql dump utility)
Problem: mysqldump not sanitizing the version string obtained from server which may lead to injecting malicious commands to the output. Fix: added function sanitizing the version string by cutting off illegal part and issuing warning. Test: check the server version in the output with and without injected payload. Change-Id: I1f19e1c90bdb8d444285e427092face3bb16da01
1 parent c7e824d commit f351ea9

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

client/mysqldump.cc

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,36 @@ static void short_usage(void) {
759759
printf("For more options, use %s --help\n", my_progname);
760760
}
761761

762+
static void get_safe_server_info(char *safe_server_info,
763+
size_t safe_server_info_len) {
764+
const char *server_info = mysql_get_server_info(&mysql_connection);
765+
if (server_info == nullptr) {
766+
safe_server_info[0] = 0;
767+
return;
768+
}
769+
DBUG_EXECUTE_IF("server_version_injection_test", {
770+
const char *payload = "8.0.0-injection_test\n\\! touch /tmp/xxx";
771+
server_info = payload;
772+
});
773+
for (size_t i = 0; i < safe_server_info_len; ++i) {
774+
// End of string.
775+
if (server_info[i] == 0) {
776+
safe_server_info[i] = 0;
777+
return;
778+
}
779+
// Version may include only alphanumeric and punctuation characters.
780+
// Cut off the rest of the string if incorrect character found.
781+
if (!(isalnum(server_info[i]) || ispunct(server_info[i]))) {
782+
safe_server_info[i] = 0;
783+
fprintf(stderr,
784+
"-- Warning: version string returned by server is incorrect.\n");
785+
return;
786+
}
787+
safe_server_info[i] = server_info[i];
788+
}
789+
safe_server_info[safe_server_info_len - 1] = 0;
790+
}
791+
762792
static void write_header(FILE *sql_file, char *db_name) {
763793
if (opt_xml) {
764794
fputs("<?xml version=\"1.0\"?>\n", sql_file);
@@ -777,15 +807,16 @@ static void write_header(FILE *sql_file, char *db_name) {
777807

778808
bool freemem = false;
779809
char const *text = fix_identifier_with_newline(db_name, &freemem);
810+
char safe_server_info[SERVER_VERSION_LENGTH];
811+
get_safe_server_info(safe_server_info, SERVER_VERSION_LENGTH);
780812
print_comment(sql_file, false, "-- Host: %s Database: %s\n",
781813
current_host ? current_host : "localhost", text);
782814
if (freemem) my_free(const_cast<char *>(text));
783815

784816
print_comment(
785817
sql_file, false,
786818
"-- ------------------------------------------------------\n");
787-
print_comment(sql_file, false, "-- Server version\t%s\n",
788-
mysql_get_server_info(&mysql_connection));
819+
print_comment(sql_file, false, "-- Server version\t%s\n", safe_server_info);
789820

790821
if (opt_set_charset)
791822
fprintf(
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#
2+
# Bug#36248967: Security issue in mysqldump (mysql dump utility)
3+
#
4+
CREATE DATABASE test_bug36248967;
5+
-- Run mysqldump with payload injected to server version.
6+
A warning must be issued.
7+
-- Warning: version string returned by server is incorrect.
8+
The test version must be found:
9+
Pattern found.
10+
The test injected string must not be found:
11+
Pattern not found.
12+
-- Run mysqldump with correct server version.
13+
A warning must not be issued.
14+
DROP DATABASE test_bug36248967;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--source include/have_debug.inc
2+
3+
--echo #
4+
--echo # Bug#36248967: Security issue in mysqldump (mysql dump utility)
5+
--echo #
6+
7+
let $grep_file=$MYSQLTEST_VARDIR/tmp/bug36248967.sql;
8+
let $grep_output=boolean;
9+
10+
CREATE DATABASE test_bug36248967;
11+
12+
--echo -- Run mysqldump with payload injected to server version.
13+
--echo A warning must be issued.
14+
--exec $MYSQL_DUMP --debug="d,server_version_injection_test" --result-file=$grep_file test_bug36248967 2>&1
15+
16+
--echo The test version must be found:
17+
let $grep_pattern=8.0.0-injection_test;
18+
--source include/grep_pattern.inc
19+
20+
--echo The test injected string must not be found:
21+
let $grep_pattern=\\! touch /tmp/xxx;
22+
--source include/grep_pattern.inc
23+
24+
--echo -- Run mysqldump with correct server version.
25+
--exec $MYSQL_DUMP --result-file=$grep_file test_bug36248967 2>&1
26+
--echo A warning must not be issued.
27+
28+
#Cleanup
29+
--remove_file $grep_file
30+
DROP DATABASE test_bug36248967;

0 commit comments

Comments
 (0)