Confirm MySQL SET forms that change server state
SET PASSWORD, SET GLOBAL and SET PERSIST (also as @@GLOBAL.x) change the server or the database account rather than the session, so they need confirmation like other writes. Session variables stay a read.
This commit is contained in:
@@ -43,13 +43,15 @@ class SqlGuard
|
||||
* What makes a statement that starts as a read change something:
|
||||
* a data-modifying CTE (WITH x AS (DELETE ...)), SELECT ... INTO,
|
||||
* SELECT ... FOR UPDATE, EXPLAIN ANALYZE (runs the statement),
|
||||
* SET ROLE / SET SESSION AUTHORIZATION, and functions with side
|
||||
* SET ROLE / SET SESSION AUTHORIZATION, MySQL's SET PASSWORD /
|
||||
* GLOBAL / PERSIST, and functions with side
|
||||
* effects. Statements that don't start as a read always need
|
||||
* confirmation, so INSERT, DROP, CREATE etc. don't need to be here.
|
||||
*/
|
||||
private const WRITES_INSIDE_READ = [
|
||||
'/\b(INSERT|UPDATE|DELETE|MERGE|INTO|ANALYZE)\b/i',
|
||||
'/^SET\s+(SESSION\s+|LOCAL\s+)?(ROLE|SESSION\s+AUTHORIZATION)\b/i',
|
||||
'/^SET\s+(PASSWORD|GLOBAL|PERSIST|PERSIST_ONLY)\b|^SET\s+@@(GLOBAL|PERSIST|PERSIST_ONLY)\./i',
|
||||
'/\b(pg_terminate_backend|pg_cancel_backend|pg_reload_conf|set_config|setval|nextval|lo_create|lo_put|lo_unlink|pg_switch_wal|pg_create_restore_point|pg_advisory_lock)\s*\(/i',
|
||||
];
|
||||
|
||||
|
||||
@@ -71,6 +71,8 @@ class SqlGuardTest extends TestCase
|
||||
['SHOW search_path'],
|
||||
['EXPLAIN SELECT 1'],
|
||||
["SET myvar.uid = 'alice'"],
|
||||
['SET @uid = 5'],
|
||||
['SET SESSION sql_mode = \'\''],
|
||||
["SELECT \$\$DELETE FROM x\$\$"],
|
||||
["SELECT E'it\\'s delete' FROM t"],
|
||||
['VALUES (1)'],
|
||||
@@ -109,6 +111,10 @@ class SqlGuardTest extends TestCase
|
||||
['EXPLAIN ANALYZE DELETE FROM t'],
|
||||
['SET ROLE postgres'],
|
||||
['SET SESSION AUTHORIZATION postgres'],
|
||||
["SET PASSWORD = 'x'"],
|
||||
['SET GLOBAL max_connections = 10'],
|
||||
['SET PERSIST max_connections = 10'],
|
||||
['SET @@GLOBAL.max_connections = 10'],
|
||||
['SELECT pg_terminate_backend(123)'],
|
||||
["SELECT set_config('x', 'y', false)"],
|
||||
["SELECT setval('seq', 1)"],
|
||||
|
||||
Reference in New Issue
Block a user