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 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

View File

@@ -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

View File

@@ -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: