Skip to content

Commit a269478

Browse files
NikolaySclaude
andcommitted
fix(roles): SQL injection in role management
Replace string concatenation with format() function in role management scripts to prevent SQL injection with special characters in usernames or passwords. Use %I for identifier quoting and %L for literal escaping. While these scripts are intended for DBA use in interactive sessions, using format() is better practice and handles edge cases with special characters. Files modified: - roles/alter_user_with_random_password.psql - roles/create_user_with_random_password.psql Co-Authored-By: Claude <[email protected]>
1 parent 1d47ee5 commit a269478

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)