With SQL functions (
LANGUAGE sql), the answer is generally yes. Passed parameters are treated as values and SQL-injection is not possible - as long as you don't call unsafe functions from within and pass parameters.
With PL/pgSQL functions (
LANGUAGE plpgsql), the answer is normally yes.
However, PL/pgSQL allows for dynamic SQL where passed parameters (or parts) can be treated as identifiers or code, which makes SQL injection possible. You cannot tell from outside whether the function body deals with that properly. Tools are provided. Basically:
If parameters should be treated as values or plain text in dynamic SQL with
If parameters should be treated as identifiers, properly sanitize them with one of these tools:
Code examples in related answers on SO here or here:
Never just build a string from user input and execute. (This includes identifiers, which have to be treated like user input when building dynamic SQL!)
More about implications on performance in this related answer:
PostgreSQL Stored Procedure Performance
Basics on SQL-injection:
Similar considerations may apply to other server-side languages that allow dynamic SQL.