Skip to content

Commit 62376b0

Browse files
NikolaySclaude
andcommitted
🔒 SECURITY: Fix SQL injection vulnerabilities in role management
**Critical Security Fixes:** - Fix 5 SQL injection vulnerabilities in user/password management scripts - Replace dangerous string concatenation with secure format() function - Use %I placeholder for safe identifier handling (usernames) - Use %L placeholder for safe literal handling (passwords) **Files Fixed:** - roles/alter_user_with_random_password.psql (3 vulnerabilities) - roles/create_user_with_random_password.psql (2 vulnerabilities) **Security Impact:** - Prevents username injection attacks - Prevents password injection attacks - Eliminates potential privilege escalation - Blocks arbitrary SQL command execution **Technical Details:** Before (vulnerable): ```sql sql := 'alter role ' || username || ' password ''' || pwd || ''';'; ``` After (secure): ```sql sql := format('alter role %I password %L', username, pwd); ``` This comprehensive fix addresses all identified SQL injection attack vectors in the postgres_dba codebase, ensuring safe role management operations. Co-Authored-By: Claude <[email protected]>
1 parent 1d47ee5 commit 62376b0

File tree

2 files changed

+12
-11
lines changed

2 files changed

+12
-11
lines changed

roles/alter_user_with_random_password.psql

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,17 @@ begin
4343
j := int4(random() * allowed_len);
4444
pwd := pwd || substr(allowed, j+1, 1);
4545
end loop;
46-
sql := 'alter role ' || current_setting('postgres_dba.username')::text || ' password ''' || pwd || ''';';
46+
sql := format('alter role %I password %L', current_setting('postgres_dba.username')::text, pwd);
4747
raise debug 'SQL: %', sql;
4848
execute sql;
49-
sql := 'alter role ' || current_setting('postgres_dba.username')::text
50-
|| (case when lower(current_setting('postgres_dba.is_superuser')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' superuser' else '' end)
51-
|| ';';
49+
sql := format('alter role %I%s',
50+
current_setting('postgres_dba.username')::text,
51+
(case when lower(current_setting('postgres_dba.is_superuser')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' superuser' else '' end));
5252
raise debug 'SQL: %', sql;
5353
execute sql;
54-
sql := 'alter role ' || current_setting('postgres_dba.username')::text
55-
|| (case when lower(current_setting('postgres_dba.login')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' login' else '' end)
56-
|| ';';
54+
sql := format('alter role %I%s',
55+
current_setting('postgres_dba.username')::text,
56+
(case when lower(current_setting('postgres_dba.login')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' login' else '' end));
5757
raise debug 'SQL: %', sql;
5858
execute sql;
5959
raise debug 'User % altered, password: %', current_setting('postgres_dba.username')::text, pwd;

roles/create_user_with_random_password.psql

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ begin
4343
j := int4(random() * allowed_len);
4444
pwd := pwd || substr(allowed, j+1, 1);
4545
end loop;
46-
sql := 'create role ' || current_setting('postgres_dba.username')::text
47-
|| (case when lower(current_setting('postgres_dba.is_superuser')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' superuser' else '' end)
48-
|| (case when lower(current_setting('postgres_dba.login')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' login' else '' end)
49-
|| ' password ''' || pwd || ''';';
46+
sql := format('create role %I%s%s password %L',
47+
current_setting('postgres_dba.username')::text,
48+
(case when lower(current_setting('postgres_dba.is_superuser')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' superuser' else '' end),
49+
(case when lower(current_setting('postgres_dba.login')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' login' else '' end),
50+
pwd);
5051
raise debug 'SQL: %', sql;
5152
execute sql;
5253
raise info 'User % created, password: %', current_setting('postgres_dba.username')::text, pwd;

0 commit comments

Comments
 (0)