Courses

PostgreSQL Extension and User-Defined Functions
OSWE · Chapter 13

PostgreSQL Extension and User-Defined Functions

PostgreSQL supports loading compiled C-language extensions and User-Defined Functions (UDFs) directly into the server process. If an attacker can gain the privileges required to create such a function, they can execute arbitrary native code on the database host.

Key concepts

  • C-language UDFs are loaded as shared libraries (`.so`/`.dll`) and run inside the PostgreSQL server process itself — a UDF vulnerability is a server compromise, not just a data breach.
  • Creating a C UDF normally requires superuser privileges, so this is usually a post-exploitation escalation technique after achieving admin-level DB access, not an initial foothold.
  • `CREATE FUNCTION ... AS '/path/to/lib', 'symbol' LANGUAGE C` is the syntax that registers a native function — the path and symbol are exactly what an attacker controls if they can write to disk and reach this privilege level.
  • Hardening: restrict filesystem write access for the postgres service account, and disable/restrict `CREATE FUNCTION ... LANGUAGE C` to trusted roles only.

Example

-- Registering a native extension function (requires superuser + a compiled shared object)
CREATE FUNCTION add_one(integer) RETURNS integer
  AS '/usr/lib/postgresql/funcs', 'add_one'
  LANGUAGE C STRICT;

Try it yourself

Read the PostgreSQL C-language functions documentation and explain, in your own words, why requiring superuser privileges to load a C UDF limits (but does not eliminate) the risk of this technique.

@ Daniel Burlacu