1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-35522: MariaDB Audit does not detect all DCLs forms when masking password

1. skip OR REPLACE
 (to make it filter_query_type made recursive)

2. skip SET STATEMENT ... FOR before checking
statements with passwords
This commit is contained in:
Oleksandr Byelkin
2024-11-29 11:45:01 +01:00
parent 3de412fbe8
commit 5c86f3df33
3 changed files with 142 additions and 52 deletions

View File

@@ -1,3 +1,6 @@
#
# MDEV-35507 and MDEV-35522
#
install plugin ed25519 soname 'auth_ed25519'; install plugin ed25519 soname 'auth_ed25519';
install plugin server_audit soname 'server_audit'; install plugin server_audit soname 'server_audit';
set global server_audit_file_path='server_audit.log'; set global server_audit_file_path='server_audit.log';
@@ -6,17 +9,25 @@ set global server_audit_logging=on;
# unsafe to log passwords (pwd-123) # unsafe to log passwords (pwd-123)
CREATE USER u1 IDENTIFIED BY 'pwd_123'; CREATE USER u1 IDENTIFIED BY 'pwd_123';
create user u2 IDENTIFIED VIA ed25519 USING PASSWORD('pwd_123'); create user u2 IDENTIFIED VIA ed25519 USING PASSWORD('pwd_123');
CREATE OR REPLACE USER u1 IDENTIFIED BY 'pwd_123';
SET PASSWORD FOR u1 = PASSWORD('pwd_123'); SET PASSWORD FOR u1 = PASSWORD('pwd_123');
ALTER USER u1 IDENTIFIED BY 'pwd_123'; ALTER USER u1 IDENTIFIED BY 'pwd_123';
ALTER USER if exists u1 IDENTIFIED BY 'pwd_123';
SET STATEMENT max_statement_time=10 FOR ALTER USER u1 IDENTIFIED BY 'pwd_123';
alter user u2 identified VIA ed25519 USING password('pwd_123'); alter user u2 identified VIA ed25519 USING password('pwd_123');
GRANT ALL ON test TO u1 IDENTIFIED BY "pwd_123"; GRANT ALL ON test TO u1 IDENTIFIED BY "pwd_123";
GRANT ALL ON test TO u1 identified VIA ed25519 as password('pwd_123') or ed25519 using password('pwd_123'); GRANT ALL ON test TO u1 identified VIA ed25519 as password('pwd_123') or ed25519 using password('pwd_123');
CREATE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123");
CREATE OR REPLACE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123");
CREATE OR REPLACE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123");
# pattern should not be found # pattern should not be found
NOT FOUND /pwd_123/ in server_audit.log NOT FOUND /pwd_123/ in server_audit.log
# pattern should not be found # pattern should not be found
# cleaunup # cleaunup
DROP SERVER s1;
DROP USER u1; DROP USER u1;
DROP USER u2; DROP USER u2;
set global server_audit_logging=off; set global server_audit_logging=off;
UNINSTALL PLUGIN ed25519; UNINSTALL PLUGIN ed25519;
UNINSTALL PLUGIN server_audit; UNINSTALL PLUGIN server_audit;
# end of 10.5 tests

View File

@@ -13,6 +13,10 @@ if (!$AUTH_ED25519_SO) {
let $MYSQLD_DATADIR= `SELECT @@datadir`; let $MYSQLD_DATADIR= `SELECT @@datadir`;
let SEARCH_FILE= $MYSQLD_DATADIR/server_audit.log; let SEARCH_FILE= $MYSQLD_DATADIR/server_audit.log;
--echo #
--echo # MDEV-35507 and MDEV-35522
--echo #
install plugin ed25519 soname 'auth_ed25519'; install plugin ed25519 soname 'auth_ed25519';
install plugin server_audit soname 'server_audit'; install plugin server_audit soname 'server_audit';
@@ -25,17 +29,24 @@ set global server_audit_logging=on;
CREATE USER u1 IDENTIFIED BY 'pwd_123'; CREATE USER u1 IDENTIFIED BY 'pwd_123';
create user u2 IDENTIFIED VIA ed25519 USING PASSWORD('pwd_123'); create user u2 IDENTIFIED VIA ed25519 USING PASSWORD('pwd_123');
CREATE OR REPLACE USER u1 IDENTIFIED BY 'pwd_123';
SET PASSWORD FOR u1 = PASSWORD('pwd_123'); SET PASSWORD FOR u1 = PASSWORD('pwd_123');
ALTER USER u1 IDENTIFIED BY 'pwd_123'; ALTER USER u1 IDENTIFIED BY 'pwd_123';
ALTER USER if exists u1 IDENTIFIED BY 'pwd_123';
SET STATEMENT max_statement_time=10 FOR ALTER USER u1 IDENTIFIED BY 'pwd_123';
alter user u2 identified VIA ed25519 USING password('pwd_123'); alter user u2 identified VIA ed25519 USING password('pwd_123');
GRANT ALL ON test TO u1 IDENTIFIED BY "pwd_123"; GRANT ALL ON test TO u1 IDENTIFIED BY "pwd_123";
GRANT ALL ON test TO u1 identified VIA ed25519 as password('pwd_123') or ed25519 using password('pwd_123'); GRANT ALL ON test TO u1 identified VIA ed25519 as password('pwd_123') or ed25519 using password('pwd_123');
CREATE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123");
CREATE OR REPLACE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123");
CREATE OR REPLACE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123");
--let SEARCH_PATTERN=pwd_123 --let SEARCH_PATTERN=pwd_123
--echo # pattern should not be found --echo # pattern should not be found
--source include/search_pattern_in_file.inc --source include/search_pattern_in_file.inc
--echo # pattern should not be found --echo # pattern should not be found
--echo # cleaunup --echo # cleaunup
DROP SERVER s1;
DROP USER u1; DROP USER u1;
DROP USER u2; DROP USER u2;
set global server_audit_logging=off; set global server_audit_logging=off;
@@ -44,3 +55,5 @@ set global server_audit_logging=off;
UNINSTALL PLUGIN ed25519; UNINSTALL PLUGIN ed25519;
UNINSTALL PLUGIN server_audit; UNINSTALL PLUGIN server_audit;
--enable_warnings --enable_warnings
--echo # end of 10.5 tests

View File

@@ -818,6 +818,7 @@ enum sa_keywords
SQLCOM_TRUNCATE, SQLCOM_TRUNCATE,
SQLCOM_QUERY_ADMIN, SQLCOM_QUERY_ADMIN,
SQLCOM_DCL, SQLCOM_DCL,
SQLCOM_FOUND=-1,
}; };
struct sa_keyword struct sa_keyword
@@ -829,30 +830,87 @@ struct sa_keyword
}; };
struct sa_keyword xml_word= {3, "XML", 0, SQLCOM_NOTHING}; struct sa_keyword xml_word[]=
struct sa_keyword user_word= {4, "USER", 0, SQLCOM_NOTHING}; {
struct sa_keyword data_word= {4, "DATA", 0, SQLCOM_NOTHING}; {3, "XML", 0, SQLCOM_FOUND},
struct sa_keyword server_word= {6, "SERVER", 0, SQLCOM_NOTHING}; {0, NULL, 0, SQLCOM_NOTHING}
struct sa_keyword master_word= {6, "MASTER", 0, SQLCOM_NOTHING}; };
struct sa_keyword password_word= {8, "PASSWORD", 0, SQLCOM_NOTHING}; struct sa_keyword user_word[]=
struct sa_keyword function_word= {8, "FUNCTION", 0, SQLCOM_NOTHING}; {
struct sa_keyword statement_word= {9, "STATEMENT", 0, SQLCOM_NOTHING}; {4, "USER", 0, SQLCOM_FOUND},
struct sa_keyword procedure_word= {9, "PROCEDURE", 0, SQLCOM_NOTHING}; {0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword data_word[]=
{
{4, "DATA", 0, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword server_word[]=
{
{6, "SERVER", 0, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword master_word[]=
{
{6, "MASTER", 0, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword password_word[]=
{
{8, "PASSWORD", 0, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword function_word[]=
{
{8, "FUNCTION", 0, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword statement_word[]=
{
{9, "STATEMENT", 0, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword procedure_word[]=
{
{9, "PROCEDURE", 0, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword replace_user_word[]=
{
{7, "REPLACE", user_word, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword or_replace_user_word[]=
{
{2, "OR", replace_user_word, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword replace_server_word[]=
{
{7, "REPLACE", server_word, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword or_replace_server_word[]=
{
{2, "OR", replace_server_word, SQLCOM_FOUND},
{0, NULL, 0, SQLCOM_NOTHING}
};
struct sa_keyword keywords_to_skip[]= struct sa_keyword keywords_to_skip[]=
{ {
{3, "SET", &statement_word, SQLCOM_QUERY_ADMIN}, {3, "SET", statement_word, SQLCOM_QUERY_ADMIN},
{0, NULL, 0, SQLCOM_DDL} {0, NULL, 0, SQLCOM_NOTHING}
}; };
struct sa_keyword not_ddl_keywords[]= struct sa_keyword not_ddl_keywords[]=
{ {
{4, "DROP", &user_word, SQLCOM_DCL}, {4, "DROP", user_word, SQLCOM_DCL},
{6, "CREATE", &user_word, SQLCOM_DCL}, {6, "CREATE", user_word, SQLCOM_DCL},
{6, "RENAME", &user_word, SQLCOM_DCL}, {6, "CREATE", or_replace_user_word, SQLCOM_DCL},
{0, NULL, 0, SQLCOM_DDL} {6, "RENAME", user_word, SQLCOM_DCL},
{0, NULL, 0, SQLCOM_NOTHING}
}; };
@@ -863,7 +921,7 @@ struct sa_keyword ddl_keywords[]=
{6, "CREATE", 0, SQLCOM_DDL}, {6, "CREATE", 0, SQLCOM_DDL},
{6, "RENAME", 0, SQLCOM_DDL}, {6, "RENAME", 0, SQLCOM_DDL},
{8, "TRUNCATE", 0, SQLCOM_DDL}, {8, "TRUNCATE", 0, SQLCOM_DDL},
{0, NULL, 0, SQLCOM_DDL} {0, NULL, 0, SQLCOM_NOTHING}
}; };
@@ -871,15 +929,15 @@ struct sa_keyword dml_keywords[]=
{ {
{2, "DO", 0, SQLCOM_DML}, {2, "DO", 0, SQLCOM_DML},
{4, "CALL", 0, SQLCOM_DML}, {4, "CALL", 0, SQLCOM_DML},
{4, "LOAD", &data_word, SQLCOM_DML}, {4, "LOAD", data_word, SQLCOM_DML},
{4, "LOAD", &xml_word, SQLCOM_DML}, {4, "LOAD", xml_word, SQLCOM_DML},
{6, "DELETE", 0, SQLCOM_DML}, {6, "DELETE", 0, SQLCOM_DML},
{6, "INSERT", 0, SQLCOM_DML}, {6, "INSERT", 0, SQLCOM_DML},
{6, "SELECT", 0, SQLCOM_DML}, {6, "SELECT", 0, SQLCOM_DML},
{6, "UPDATE", 0, SQLCOM_DML}, {6, "UPDATE", 0, SQLCOM_DML},
{7, "HANDLER", 0, SQLCOM_DML}, {7, "HANDLER", 0, SQLCOM_DML},
{7, "REPLACE", 0, SQLCOM_DML}, {7, "REPLACE", 0, SQLCOM_DML},
{0, NULL, 0, SQLCOM_DML} {0, NULL, 0, SQLCOM_NOTHING}
}; };
@@ -887,38 +945,41 @@ struct sa_keyword dml_no_select_keywords[]=
{ {
{2, "DO", 0, SQLCOM_DML}, {2, "DO", 0, SQLCOM_DML},
{4, "CALL", 0, SQLCOM_DML}, {4, "CALL", 0, SQLCOM_DML},
{4, "LOAD", &data_word, SQLCOM_DML}, {4, "LOAD", data_word, SQLCOM_DML},
{4, "LOAD", &xml_word, SQLCOM_DML}, {4, "LOAD", xml_word, SQLCOM_DML},
{6, "DELETE", 0, SQLCOM_DML}, {6, "DELETE", 0, SQLCOM_DML},
{6, "INSERT", 0, SQLCOM_DML}, {6, "INSERT", 0, SQLCOM_DML},
{6, "UPDATE", 0, SQLCOM_DML}, {6, "UPDATE", 0, SQLCOM_DML},
{7, "HANDLER", 0, SQLCOM_DML}, {7, "HANDLER", 0, SQLCOM_DML},
{7, "REPLACE", 0, SQLCOM_DML}, {7, "REPLACE", 0, SQLCOM_DML},
{0, NULL, 0, SQLCOM_DML} {0, NULL, 0, SQLCOM_NOTHING}
}; };
struct sa_keyword dcl_keywords[]= struct sa_keyword dcl_keywords[]=
{ {
{6, "CREATE", &user_word, SQLCOM_DCL}, {6, "CREATE", user_word, SQLCOM_DCL},
{4, "DROP", &user_word, SQLCOM_DCL}, {6, "CREATE", or_replace_user_word, SQLCOM_DCL},
{6, "RENAME", &user_word, SQLCOM_DCL}, {4, "DROP", user_word, SQLCOM_DCL},
{6, "RENAME", user_word, SQLCOM_DCL},
{5, "GRANT", 0, SQLCOM_DCL}, {5, "GRANT", 0, SQLCOM_DCL},
{6, "REVOKE", 0, SQLCOM_DCL}, {6, "REVOKE", 0, SQLCOM_DCL},
{3, "SET", &password_word, SQLCOM_DCL}, {3, "SET", password_word, SQLCOM_DCL},
{0, NULL, 0, SQLCOM_DDL} {0, NULL, 0, SQLCOM_NOTHING}
}; };
struct sa_keyword passwd_keywords[]= struct sa_keyword passwd_keywords[]=
{ {
{3, "SET", &password_word, SQLCOM_SET_OPTION}, {3, "SET", password_word, SQLCOM_SET_OPTION},
{5, "ALTER", &server_word, SQLCOM_ALTER_SERVER}, {5, "ALTER", server_word, SQLCOM_ALTER_SERVER},
{5, "ALTER", &user_word, SQLCOM_ALTER_USER}, {5, "ALTER", user_word, SQLCOM_ALTER_USER},
{5, "GRANT", 0, SQLCOM_GRANT}, {5, "GRANT", 0, SQLCOM_GRANT},
{6, "CREATE", &user_word, SQLCOM_CREATE_USER}, {6, "CREATE", user_word, SQLCOM_CREATE_USER},
{6, "CREATE", &server_word, SQLCOM_CREATE_SERVER}, {6, "CREATE", or_replace_user_word, SQLCOM_CREATE_USER},
{6, "CHANGE", &master_word, SQLCOM_CHANGE_MASTER}, {6, "CREATE", server_word, SQLCOM_CREATE_SERVER},
{6, "CREATE", or_replace_server_word, SQLCOM_CREATE_SERVER},
{6, "CHANGE", master_word, SQLCOM_CHANGE_MASTER},
{0, NULL, 0, SQLCOM_NOTHING} {0, NULL, 0, SQLCOM_NOTHING}
}; };
@@ -1732,7 +1793,7 @@ static int filter_query_type(const char *query, struct sa_keyword *kwd)
query++; query++;
} }
qwe_in_list= 0; qwe_in_list= SQLCOM_NOTHING;
if (!(len= get_next_word(query, fword))) if (!(len= get_next_word(query, fword)))
goto not_in_list; goto not_in_list;
query+= len+1; query+= len+1;
@@ -1750,8 +1811,7 @@ static int filter_query_type(const char *query, struct sa_keyword *kwd)
query++; query++;
nlen= get_next_word(query, nword); nlen= get_next_word(query, nword);
} }
if (l_keywords->next->length != nlen || if (filter_query_type(query, l_keywords->next) == SQLCOM_NOTHING)
strncmp(l_keywords->next->wd, nword, nlen) != 0)
goto do_loop; goto do_loop;
} }
@@ -1766,6 +1826,25 @@ not_in_list:
return qwe_in_list; return qwe_in_list;
} }
static const char *skip_set_statement(const char *query)
{
if (filter_query_type(query, keywords_to_skip))
{
char fword[MAX_KEYWORD + 1];
int len;
do
{
len= get_next_word(query, fword);
query+= len ? len : 1;
if (len == 3 && strncmp(fword, "FOR", 3) == 0)
break;
} while (*query);
if (*query == 0)
return 0;
}
return query;
}
static int log_statement_ex(const struct connection_info *cn, static int log_statement_ex(const struct connection_info *cn,
time_t ev_time, unsigned long thd_id, time_t ev_time, unsigned long thd_id,
@@ -1809,21 +1888,8 @@ static int log_statement_ex(const struct connection_info *cn,
{ {
const char *orig_query= query; const char *orig_query= query;
if (filter_query_type(query, keywords_to_skip)) if ((query= skip_set_statement(query)) == SQLCOM_NOTHING)
{ return 0;
char fword[MAX_KEYWORD + 1];
int len;
do
{
len= get_next_word(query, fword);
query+= len ? len : 1;
if (len == 3 && strncmp(fword, "FOR", 3) == 0)
break;
} while (*query);
if (*query == 0)
return 0;
}
if (events & EVENT_QUERY_DDL) if (events & EVENT_QUERY_DDL)
{ {
@@ -1879,7 +1945,7 @@ do_log_query:
if (query_log_limit > 0 && uh_buffer_size > query_log_limit+2) if (query_log_limit > 0 && uh_buffer_size > query_log_limit+2)
uh_buffer_size= query_log_limit+2; uh_buffer_size= query_log_limit+2;
switch (filter_query_type(query, passwd_keywords)) switch (filter_query_type(skip_set_statement(query), passwd_keywords))
{ {
case SQLCOM_GRANT: case SQLCOM_GRANT:
case SQLCOM_CREATE_USER: case SQLCOM_CREATE_USER: