安全引用类型名称以防止 SQL 注入

Eva*_*oll 2 postgresql sql-injection datatypes dynamic-sql

我将如何引用类型名称以防止 SQL 注入。例如,拿这个

SELECT FORMAT('SELECT CAST(%L AS %s);', '5.42', 'int');
                                                 ^ Quote this
Run Code Online (Sandbox Code Playgroud)

这很好用,但如果'int'相反,''int); DROP DATABASE foo;SELECT ('你会遇到一些问题,

SELECT FORMAT('SELECT CAST(%L AS %s);', '5.42', 'int); DROP DATABASE foo;SELECT (');
                          format                          
----------------------------------------------------------
 SELECT CAST('5.42' AS int); DROP DATABASE foo;SELECT ();
(1 row)
Run Code Online (Sandbox Code Playgroud)

我将如何使用动态 SQL 安全地转换为运行时提供的类型?如果我使用%I而不是%s我得到一个标识符(用 安全引用",但类型名称不是标识符并且不能使用双引号)。

受到try_castJasen提供的“PostgreSQL 替代 SQL Server功能”的回答的启发

Erw*_*ter 5

我将如何引用类型名称以防止 SQL 注入。

你不需要format_type()为目的。你可能在那里误解了安德鲁。您所需要的只是演员阵容regtype

SELECT format('SELECT cast(%L AS %s);', '5.42', 'int'::regtype);
Run Code Online (Sandbox Code Playgroud)

值的text表示regtype是标准 SQL 名称并在需要时自动引用 - 并且该值被text隐式转换为连接。演示:

SELECT 'varchar(20)'::regtype, 'int'::regtype, '"char"'::regtype;

regtype           | regtype | regtype
------------------+---------+---------
character varying | integer | "char"
Run Code Online (Sandbox Code Playgroud)

format_type()只会用于添加类型修饰符(在演员表中丢失),这是一个正交问题。有关的: