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:
@@ -1,3 +1,6 @@
|
||||
#
|
||||
# MDEV-35507 and MDEV-35522
|
||||
#
|
||||
install plugin ed25519 soname 'auth_ed25519';
|
||||
install plugin server_audit soname 'server_audit';
|
||||
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)
|
||||
CREATE USER u1 IDENTIFIED BY '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');
|
||||
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');
|
||||
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');
|
||||
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
|
||||
NOT FOUND /pwd_123/ in server_audit.log
|
||||
# pattern should not be found
|
||||
# cleaunup
|
||||
DROP SERVER s1;
|
||||
DROP USER u1;
|
||||
DROP USER u2;
|
||||
set global server_audit_logging=off;
|
||||
UNINSTALL PLUGIN ed25519;
|
||||
UNINSTALL PLUGIN server_audit;
|
||||
# end of 10.5 tests
|
||||
|
@@ -13,6 +13,10 @@ if (!$AUTH_ED25519_SO) {
|
||||
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||
let SEARCH_FILE= $MYSQLD_DATADIR/server_audit.log;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-35507 and MDEV-35522
|
||||
--echo #
|
||||
|
||||
install plugin ed25519 soname 'auth_ed25519';
|
||||
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 u2 IDENTIFIED VIA ed25519 USING PASSWORD('pwd_123');
|
||||
CREATE OR REPLACE USER u1 IDENTIFIED BY 'pwd_123';
|
||||
SET PASSWORD FOR u1 = PASSWORD('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');
|
||||
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');
|
||||
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
|
||||
--echo # pattern should not be found
|
||||
--source include/search_pattern_in_file.inc
|
||||
--echo # pattern should not be found
|
||||
|
||||
--echo # cleaunup
|
||||
DROP SERVER s1;
|
||||
DROP USER u1;
|
||||
DROP USER u2;
|
||||
set global server_audit_logging=off;
|
||||
@@ -44,3 +55,5 @@ set global server_audit_logging=off;
|
||||
UNINSTALL PLUGIN ed25519;
|
||||
UNINSTALL PLUGIN server_audit;
|
||||
--enable_warnings
|
||||
|
||||
--echo # end of 10.5 tests
|
||||
|
@@ -818,6 +818,7 @@ enum sa_keywords
|
||||
SQLCOM_TRUNCATE,
|
||||
SQLCOM_QUERY_ADMIN,
|
||||
SQLCOM_DCL,
|
||||
SQLCOM_FOUND=-1,
|
||||
};
|
||||
|
||||
struct sa_keyword
|
||||
@@ -829,30 +830,87 @@ struct sa_keyword
|
||||
};
|
||||
|
||||
|
||||
struct sa_keyword xml_word= {3, "XML", 0, SQLCOM_NOTHING};
|
||||
struct sa_keyword user_word= {4, "USER", 0, SQLCOM_NOTHING};
|
||||
struct sa_keyword data_word= {4, "DATA", 0, SQLCOM_NOTHING};
|
||||
struct sa_keyword server_word= {6, "SERVER", 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 function_word= {8, "FUNCTION", 0, SQLCOM_NOTHING};
|
||||
struct sa_keyword statement_word= {9, "STATEMENT", 0, SQLCOM_NOTHING};
|
||||
struct sa_keyword procedure_word= {9, "PROCEDURE", 0, SQLCOM_NOTHING};
|
||||
struct sa_keyword xml_word[]=
|
||||
{
|
||||
{3, "XML", 0, SQLCOM_FOUND},
|
||||
{0, NULL, 0, SQLCOM_NOTHING}
|
||||
};
|
||||
struct sa_keyword user_word[]=
|
||||
{
|
||||
{4, "USER", 0, SQLCOM_FOUND},
|
||||
{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[]=
|
||||
{
|
||||
{3, "SET", &statement_word, SQLCOM_QUERY_ADMIN},
|
||||
{0, NULL, 0, SQLCOM_DDL}
|
||||
{3, "SET", statement_word, SQLCOM_QUERY_ADMIN},
|
||||
{0, NULL, 0, SQLCOM_NOTHING}
|
||||
};
|
||||
|
||||
|
||||
struct sa_keyword not_ddl_keywords[]=
|
||||
{
|
||||
{4, "DROP", &user_word, SQLCOM_DCL},
|
||||
{6, "CREATE", &user_word, SQLCOM_DCL},
|
||||
{6, "RENAME", &user_word, SQLCOM_DCL},
|
||||
{0, NULL, 0, SQLCOM_DDL}
|
||||
{4, "DROP", user_word, SQLCOM_DCL},
|
||||
{6, "CREATE", user_word, SQLCOM_DCL},
|
||||
{6, "CREATE", or_replace_user_word, SQLCOM_DCL},
|
||||
{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, "RENAME", 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},
|
||||
{4, "CALL", 0, SQLCOM_DML},
|
||||
{4, "LOAD", &data_word, SQLCOM_DML},
|
||||
{4, "LOAD", &xml_word, SQLCOM_DML},
|
||||
{4, "LOAD", data_word, SQLCOM_DML},
|
||||
{4, "LOAD", xml_word, SQLCOM_DML},
|
||||
{6, "DELETE", 0, SQLCOM_DML},
|
||||
{6, "INSERT", 0, SQLCOM_DML},
|
||||
{6, "SELECT", 0, SQLCOM_DML},
|
||||
{6, "UPDATE", 0, SQLCOM_DML},
|
||||
{7, "HANDLER", 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},
|
||||
{4, "CALL", 0, SQLCOM_DML},
|
||||
{4, "LOAD", &data_word, SQLCOM_DML},
|
||||
{4, "LOAD", &xml_word, SQLCOM_DML},
|
||||
{4, "LOAD", data_word, SQLCOM_DML},
|
||||
{4, "LOAD", xml_word, SQLCOM_DML},
|
||||
{6, "DELETE", 0, SQLCOM_DML},
|
||||
{6, "INSERT", 0, SQLCOM_DML},
|
||||
{6, "UPDATE", 0, SQLCOM_DML},
|
||||
{7, "HANDLER", 0, SQLCOM_DML},
|
||||
{7, "REPLACE", 0, SQLCOM_DML},
|
||||
{0, NULL, 0, SQLCOM_DML}
|
||||
{0, NULL, 0, SQLCOM_NOTHING}
|
||||
};
|
||||
|
||||
|
||||
struct sa_keyword dcl_keywords[]=
|
||||
{
|
||||
{6, "CREATE", &user_word, SQLCOM_DCL},
|
||||
{4, "DROP", &user_word, SQLCOM_DCL},
|
||||
{6, "RENAME", &user_word, SQLCOM_DCL},
|
||||
{6, "CREATE", user_word, SQLCOM_DCL},
|
||||
{6, "CREATE", or_replace_user_word, SQLCOM_DCL},
|
||||
{4, "DROP", user_word, SQLCOM_DCL},
|
||||
{6, "RENAME", user_word, SQLCOM_DCL},
|
||||
{5, "GRANT", 0, SQLCOM_DCL},
|
||||
{6, "REVOKE", 0, SQLCOM_DCL},
|
||||
{3, "SET", &password_word, SQLCOM_DCL},
|
||||
{0, NULL, 0, SQLCOM_DDL}
|
||||
{3, "SET", password_word, SQLCOM_DCL},
|
||||
{0, NULL, 0, SQLCOM_NOTHING}
|
||||
};
|
||||
|
||||
|
||||
struct sa_keyword passwd_keywords[]=
|
||||
{
|
||||
{3, "SET", &password_word, SQLCOM_SET_OPTION},
|
||||
{5, "ALTER", &server_word, SQLCOM_ALTER_SERVER},
|
||||
{5, "ALTER", &user_word, SQLCOM_ALTER_USER},
|
||||
{3, "SET", password_word, SQLCOM_SET_OPTION},
|
||||
{5, "ALTER", server_word, SQLCOM_ALTER_SERVER},
|
||||
{5, "ALTER", user_word, SQLCOM_ALTER_USER},
|
||||
{5, "GRANT", 0, SQLCOM_GRANT},
|
||||
{6, "CREATE", &user_word, SQLCOM_CREATE_USER},
|
||||
{6, "CREATE", &server_word, SQLCOM_CREATE_SERVER},
|
||||
{6, "CHANGE", &master_word, SQLCOM_CHANGE_MASTER},
|
||||
{6, "CREATE", user_word, SQLCOM_CREATE_USER},
|
||||
{6, "CREATE", or_replace_user_word, SQLCOM_CREATE_USER},
|
||||
{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}
|
||||
};
|
||||
|
||||
@@ -1732,7 +1793,7 @@ static int filter_query_type(const char *query, struct sa_keyword *kwd)
|
||||
query++;
|
||||
}
|
||||
|
||||
qwe_in_list= 0;
|
||||
qwe_in_list= SQLCOM_NOTHING;
|
||||
if (!(len= get_next_word(query, fword)))
|
||||
goto not_in_list;
|
||||
query+= len+1;
|
||||
@@ -1750,8 +1811,7 @@ static int filter_query_type(const char *query, struct sa_keyword *kwd)
|
||||
query++;
|
||||
nlen= get_next_word(query, nword);
|
||||
}
|
||||
if (l_keywords->next->length != nlen ||
|
||||
strncmp(l_keywords->next->wd, nword, nlen) != 0)
|
||||
if (filter_query_type(query, l_keywords->next) == SQLCOM_NOTHING)
|
||||
goto do_loop;
|
||||
}
|
||||
|
||||
@@ -1766,6 +1826,25 @@ not_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,
|
||||
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;
|
||||
|
||||
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)
|
||||
if ((query= skip_set_statement(query)) == SQLCOM_NOTHING)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (events & EVENT_QUERY_DDL)
|
||||
{
|
||||
@@ -1879,7 +1945,7 @@ do_log_query:
|
||||
if (query_log_limit > 0 && 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_CREATE_USER:
|
||||
|
Reference in New Issue
Block a user