principlesqlCritical
SQL injection in Postgres functions vs prepared queries
Viewed 0 times
postgresqueriessqlpreparedinjectionfunctions
Problem
In Postgres, are prepared queries and user defined functions equivalent as a mechanism for guarding against SQL injection?
Are there particular advantages in one approach over the other?
Are there particular advantages in one approach over the other?
Solution
It depends.
Prepared statements
A.k.a. "prepared queries". These only take values when executed with
SQL functions / procedures
With
Passed parameters are treated as values and SQL-injection is not possible - as long as you don't call unsafe functions from the body and pass parameters.
PL/pgSQL functions /procedures
With
However, PL/pgSQL allows for dynamic SQL where passed parameters (or parts) are concatenated to a query string and executed with
Plain SQL statements using parameters as values are safe against SQL injection, just like SQL functions. Only use dynamic SQL where needed and follow these guidelines:
Preferably pass values as values to
Never just build strings from user input and execute. This includes identifiers, directly passed by a user or fetched from a system catalog.
-
When concatenating values in the SQL string, wrap 'strings' in single-quotes safely. Use:
-
When concatenating identifiers in the SQL string, wrap them in double-quotes safely where required. Use:
-
Concatenating other parts of the SQL code is never safe, when allowing unchecked user input in any way.
Related:
More about performance implications in this related answer:
Basics on SQL-injection:
Similar considerations apply to other server-side languages that allow dynamic SQL.
Prepared statements
A.k.a. "prepared queries". These only take values when executed with
EXECUTE. No SQL-injection possible at this stage. But you have to defend against SQL-injection while generating / concatenating the statement to be fed to PREPARE in the first place. Prepared statements are very much equivalent to stored SQL functions / procedures in this regard.SQL functions / procedures
With
LANGUAGE sql they are generally safe.Passed parameters are treated as values and SQL-injection is not possible - as long as you don't call unsafe functions from the body and pass parameters.
PL/pgSQL functions /procedures
With
LANGUAGE plpgsql they are normally safe.However, PL/pgSQL allows for dynamic SQL where passed parameters (or parts) are concatenated to a query string and executed with
EXECUTE. This can convert user input to SQL code and make SQL injection possible. Tools are there to do it safely. You cannot tell from outside whether the function body handles it properly, you have to look at the code.Plain SQL statements using parameters as values are safe against SQL injection, just like SQL functions. Only use dynamic SQL where needed and follow these guidelines:
Preferably pass values as values to
EXECUTE with the USING clause. Makes SQL injection impossible on principal. Example.Never just build strings from user input and execute. This includes identifiers, directly passed by a user or fetched from a system catalog.
-
When concatenating values in the SQL string, wrap 'strings' in single-quotes safely. Use:
format()with format specifier%L. Example.
quote_literal()orquote_nullable(). Example.
-
When concatenating identifiers in the SQL string, wrap them in double-quotes safely where required. Use:
format()with format specifier%I. Example.
quote_ident(). Example.
- a cast to a registered type -
regclassfor table names:_tbl::regclass. (Only works for existing objects!) Example.
-
Concatenating other parts of the SQL code is never safe, when allowing unchecked user input in any way.
Related:
- Refactor a PL/pgSQL function to return the output of various SELECT queries
- Define table and column names as arguments in a plpgsql function?
More about performance implications in this related answer:
- Function Performance
Basics on SQL-injection:
- http://bobby-tables.com/
Similar considerations apply to other server-side languages that allow dynamic SQL.
Context
StackExchange Database Administrators Q#49699, answer score: 58
Revisions (0)
No revisions yet.