Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf535110

Browse files
committed
Reject substituting extension schemas or owners matching ["$'\].
Substituting such values in extension scripts facilitated SQL injectionwhen @extowner@, @extschema@, or @extschema:...@ appeared inside aquoting construct (dollar quoting, '', or ""). No bundled extension wasvulnerable. Vulnerable uses do appear in a documentation example and innon-bundled extensions. Hence, the attack prerequisite was anadministrator having installed files of a vulnerable, trusted,non-bundled extension. Subject to that prerequisite, this enabled anattacker having database-level CREATE privilege to execute arbitrarycode as the bootstrap superuser. By blocking this attack in the coreserver, there's no need to modify individual extensions. Back-patch tov11 (all supported versions).Reported by Micah Gate, Valerie Woolard, Tim Carey-Smith, and ChristophBerg.Security:CVE-2023-39417
1 parente8386b2 commitf535110

File tree

7 files changed

+79
-15
lines changed

7 files changed

+79
-15
lines changed

‎src/backend/commands/extension.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,16 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
10011001
char*c_sql=read_extension_script_file(control,filename);
10021002
Datumt_sql;
10031003

1004+
/*
1005+
* We filter each substitution through quote_identifier(). When the
1006+
* arg contains one of the following characters, no one collection of
1007+
* quoting can work inside $$dollar-quoted string literals$$,
1008+
* 'single-quoted string literals', and outside of any literal. To
1009+
* avoid a security snare for extension authors, error on substitution
1010+
* for arguments containing these.
1011+
*/
1012+
constchar*quoting_relevant_chars="\"$'\\";
1013+
10041014
/* We use various functions that want to operate on text datums */
10051015
t_sql=CStringGetTextDatum(c_sql);
10061016

@@ -1030,6 +1040,11 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
10301040
t_sql,
10311041
CStringGetTextDatum("@extowner@"),
10321042
CStringGetTextDatum(qUserName));
1043+
if (strpbrk(userName,quoting_relevant_chars))
1044+
ereport(ERROR,
1045+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1046+
errmsg("invalid character in extension owner: must not contain any of \"%s\"",
1047+
quoting_relevant_chars)));
10331048
}
10341049

10351050
/*
@@ -1041,13 +1056,19 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
10411056
*/
10421057
if (!control->relocatable)
10431058
{
1059+
Datumold=t_sql;
10441060
constchar*qSchemaName=quote_identifier(schemaName);
10451061

10461062
t_sql=DirectFunctionCall3Coll(replace_text,
10471063
C_COLLATION_OID,
10481064
t_sql,
10491065
CStringGetTextDatum("@extschema@"),
10501066
CStringGetTextDatum(qSchemaName));
1067+
if (t_sql!=old&&strpbrk(schemaName,quoting_relevant_chars))
1068+
ereport(ERROR,
1069+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1070+
errmsg("invalid character in extension \"%s\" schema: must not contain any of \"%s\"",
1071+
control->name,quoting_relevant_chars)));
10511072
}
10521073

10531074
/*
@@ -1057,6 +1078,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
10571078
Assert(list_length(control->requires)==list_length(requiredSchemas));
10581079
forboth(lc,control->requires,lc2,requiredSchemas)
10591080
{
1081+
Datumold=t_sql;
10601082
char*reqextname= (char*)lfirst(lc);
10611083
Oidreqschema=lfirst_oid(lc2);
10621084
char*schemaName=get_namespace_name(reqschema);
@@ -1069,6 +1091,11 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
10691091
t_sql,
10701092
CStringGetTextDatum(repltoken),
10711093
CStringGetTextDatum(qSchemaName));
1094+
if (t_sql!=old&&strpbrk(schemaName,quoting_relevant_chars))
1095+
ereport(ERROR,
1096+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1097+
errmsg("invalid character in extension \"%s\" schema: must not contain any of \"%s\"",
1098+
reqextname,quoting_relevant_chars)));
10721099
}
10731100

10741101
/*

‎src/test/modules/test_extensions/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ PGFILEDESC = "test_extensions - regression testing for EXTENSION support"
66
EXTENSION = test_ext1 test_ext2 test_ext3 test_ext4 test_ext5 test_ext6\
77
test_ext7 test_ext8 test_ext_cine test_ext_cor\
88
test_ext_cyclic1 test_ext_cyclic2\
9+
test_ext_extschema\
910
test_ext_evttrig\
1011
test_ext_req_schema1 test_ext_req_schema2 test_ext_req_schema3
1112

@@ -15,6 +16,7 @@ DATA = test_ext1--1.0.sql test_ext2--1.0.sql test_ext3--1.0.sql \
1516
test_ext_cine--1.0.sql test_ext_cine--1.0--1.1.sql\
1617
test_ext_cor--1.0.sql\
1718
test_ext_cyclic1--1.0.sql test_ext_cyclic2--1.0.sql\
19+
test_ext_extschema--1.0.sql\
1820
test_ext_evttrig--1.0.sql test_ext_evttrig--1.0--2.0.sql\
1921
test_ext_req_schema1--1.0.sql\
2022
test_ext_req_schema2--1.0.sql\

‎src/test/modules/test_extensions/expected/test_extensions.out

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
CREATE SCHEMA has$dollar;
12
-- test some errors
23
CREATE EXTENSION test_ext1;
34
ERROR: required extension "test_ext2" is not installed
@@ -6,35 +7,35 @@ CREATE EXTENSION test_ext1 SCHEMA test_ext1;
67
ERROR: schema "test_ext1" does not exist
78
CREATE EXTENSION test_ext1 SCHEMA test_ext;
89
ERROR: schema "test_ext" does not exist
9-
CREATE SCHEMA test_ext;
10-
CREATE EXTENSION test_ext1 SCHEMA test_ext;
10+
CREATE EXTENSION test_ext1 SCHEMA has$dollar;
1111
ERROR: extension "test_ext1" must be installed in schema "test_ext1"
1212
-- finally success
13-
CREATE EXTENSION test_ext1 SCHEMAtest_ext CASCADE;
13+
CREATE EXTENSION test_ext1 SCHEMAhas$dollar CASCADE;
1414
NOTICE: installing required extension "test_ext2"
1515
NOTICE: installing required extension "test_ext3"
1616
NOTICE: installing required extension "test_ext5"
1717
NOTICE: installing required extension "test_ext4"
1818
SELECT extname, nspname, extversion, extrelocatable FROM pg_extension e, pg_namespace n WHERE extname LIKE 'test_ext%' AND e.extnamespace = n.oid ORDER BY 1;
19-
extname | nspname | extversion | extrelocatable
20-
-----------+-----------+------------+----------------
21-
test_ext1 | test_ext1 | 1.0 | f
22-
test_ext2 |test_ext | 1.0 | t
23-
test_ext3 |test_ext | 1.0 | t
24-
test_ext4 |test_ext | 1.0 | t
25-
test_ext5 |test_ext | 1.0 | t
19+
extname | nspname| extversion | extrelocatable
20+
-----------+------------+------------+----------------
21+
test_ext1 | test_ext1| 1.0 | f
22+
test_ext2 |has$dollar | 1.0 | t
23+
test_ext3 |has$dollar | 1.0 | t
24+
test_ext4 |has$dollar | 1.0 | t
25+
test_ext5 |has$dollar | 1.0 | t
2626
(5 rows)
2727

2828
CREATE EXTENSION test_ext_cyclic1 CASCADE;
2929
NOTICE: installing required extension "test_ext_cyclic2"
3030
ERROR: cyclic dependency detected between extensions "test_ext_cyclic1" and "test_ext_cyclic2"
31-
DROP SCHEMAtest_ext CASCADE;
31+
DROP SCHEMAhas$dollar CASCADE;
3232
NOTICE: drop cascades to 5 other objects
3333
DETAIL: drop cascades to extension test_ext3
3434
drop cascades to extension test_ext5
3535
drop cascades to extension test_ext2
3636
drop cascades to extension test_ext4
3737
drop cascades to extension test_ext1
38+
CREATE SCHEMA has$dollar;
3839
CREATE EXTENSION test_ext6;
3940
DROP EXTENSION test_ext6;
4041
CREATE EXTENSION test_ext6;
@@ -312,6 +313,13 @@ Objects in extension "test_ext_cine"
312313
table ext_cine_tab3
313314
(9 rows)
314315

316+
--
317+
-- Test @extschema@ syntax.
318+
--
319+
CREATE SCHEMA "has space";
320+
CREATE EXTENSION test_ext_extschema SCHEMA has$dollar;
321+
ERROR: invalid character in extension "test_ext_extschema" schema: must not contain any of ""$'\"
322+
CREATE EXTENSION test_ext_extschema SCHEMA "has space";
315323
--
316324
-- Test extension with objects outside the extension's schema.
317325
--
@@ -358,6 +366,11 @@ DROP SCHEMA test_func_dep3;
358366
--
359367
-- Test @extschema:extname@ syntax and no_relocate option
360368
--
369+
CREATE EXTENSION test_ext_req_schema1 SCHEMA has$dollar;
370+
CREATE EXTENSION test_ext_req_schema3 CASCADE;
371+
NOTICE: installing required extension "test_ext_req_schema2"
372+
ERROR: invalid character in extension "test_ext_req_schema1" schema: must not contain any of ""$'\"
373+
DROP EXTENSION test_ext_req_schema1;
361374
CREATE SCHEMA test_s_dep;
362375
CREATE EXTENSION test_ext_req_schema1 SCHEMA test_s_dep;
363376
CREATE EXTENSION test_ext_req_schema3 CASCADE;

‎src/test/modules/test_extensions/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ test_install_data += files(
2727
'test_ext_cyclic1.control',
2828
'test_ext_cyclic2--1.0.sql',
2929
'test_ext_cyclic2.control',
30+
'test_ext_extschema--1.0.sql',
31+
'test_ext_extschema.control',
3032
'test_ext_evttrig--1.0--2.0.sql',
3133
'test_ext_evttrig--1.0.sql',
3234
'test_ext_evttrig.control',

‎src/test/modules/test_extensions/sql/test_extensions.sql

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1+
CREATESCHEMAhas$dollar;
2+
13
-- test some errors
24
CREATE EXTENSION test_ext1;
35
CREATE EXTENSION test_ext1 SCHEMA test_ext1;
46
CREATE EXTENSION test_ext1 SCHEMA test_ext;
5-
CREATESCHEMAtest_ext;
6-
CREATE EXTENSION test_ext1 SCHEMA test_ext;
7+
CREATE EXTENSION test_ext1 SCHEMA has$dollar;
78

89
-- finally success
9-
CREATE EXTENSION test_ext1 SCHEMAtest_ext CASCADE;
10+
CREATE EXTENSION test_ext1 SCHEMAhas$dollar CASCADE;
1011

1112
SELECT extname, nspname, extversion, extrelocatableFROM pg_extension e, pg_namespace nWHERE extnameLIKE'test_ext%'ANDe.extnamespace=n.oidORDER BY1;
1213

1314
CREATE EXTENSION test_ext_cyclic1 CASCADE;
1415

15-
DROPSCHEMA test_ext CASCADE;
16+
DROPSCHEMA has$dollar CASCADE;
17+
CREATESCHEMAhas$dollar;
1618

1719
CREATE EXTENSION test_ext6;
1820
DROP EXTENSION test_ext6;
@@ -210,6 +212,13 @@ ALTER EXTENSION test_ext_cine UPDATE TO '1.1';
210212

211213
\dx+ test_ext_cine
212214

215+
--
216+
-- Test @extschema@ syntax.
217+
--
218+
CREATE SCHEMA"has space";
219+
CREATE EXTENSION test_ext_extschema SCHEMA has$dollar;
220+
CREATE EXTENSION test_ext_extschema SCHEMA"has space";
221+
213222
--
214223
-- Test extension with objects outside the extension's schema.
215224
--
@@ -245,6 +254,9 @@ DROP SCHEMA test_func_dep3;
245254
--
246255
-- Test @extschema:extname@ syntax and no_relocate option
247256
--
257+
CREATE EXTENSION test_ext_req_schema1 SCHEMA has$dollar;
258+
CREATE EXTENSION test_ext_req_schema3 CASCADE;
259+
DROP EXTENSION test_ext_req_schema1;
248260
CREATESCHEMAtest_s_dep;
249261
CREATE EXTENSION test_ext_req_schema1 SCHEMA test_s_dep;
250262
CREATE EXTENSION test_ext_req_schema3 CASCADE;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/* src/test/modules/test_extensions/test_ext_extschema--1.0.sql*/
2+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
3+
\echo Use"CREATE EXTENSION test_ext_extschema" to load this file. \quit
4+
5+
SELECT1AS @extschema@;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
comment = 'test @extschema@'
2+
default_version = '1.0'
3+
relocatable = false

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp