From PostgreSQL wiki
Security Release 2010-10-05 Details: External PL Vulnerabilities
Following are details of the privilege escalation exploit which was reported in CVE-2010-3433 and patched in the 2010-10-05 PostgreSQL Update Release. While this security issue is low-risk and does not affect most users, its details are complex and hence a detailed explanation is necessary in order to clearly define who it does affect.
Who is affected by this vulnerability?
Users who use external, trusted, interpreted procedural languages ("PLs"), together with privilege-changing code such as SECURITY DEFINER functions, SET ROLE and SET SESSION AUTHORIZATION.
What is the level of risk associated with this exploit?
Low. It requires all of the following:
- An attacker must have an authenticated connection to the database server.
- The attacker must be able to execute arbitrary statements over that connection.
- The attacker must have a strong knowledge of PostgreSQL.
- Your application must include procedures or functions in an external procedural language.
- These functions and procedures must be executed by users with greater privileges than the attacker, using SECURITY DEFINER or SET ROLE, and using the same connection as the attacker.
The above may seem somewhat obscure. However, the PostgreSQL project takes our status as "most secure by default" seriously and considers no security hole too small to patch. Additionally, this exploit specifically affects users who were trying to secure their data through the use of stored procedures and other mechanisms, and therefore needed to be addressed.
Which procedural languages are affected?
|PL/perl||Yes||Yes||2010-10-05 security update|
|PL/tcl||Yes||Yes||2010-10-05 security update|
|PL/pythonU||No||No||Untrusted only, not affected|
|PL/R||No||No||Untrusted only, not affected|
|PL/PHP||Yes||No|| Patch in development|
|PL/Java||???||No||Unsure if affected or not|
|PL/Ruby||???||No||Unsure if affected or not|
|PL/sh||No||No||Untrusted only, not affected|
Other PLs, such as PL/Mono, PL/C++, PL/scheme, PL/XSLT, PL/matlab, PL/LOLCODE and PL/Lua are currently limited enough in functionality and adoption that they are assumed not to represent a significant risk. Authors or contributors to all PLs are urged to examine their PLs for this vulnerability and offer patches to their users as well as updates to this page.
Am I affected if I don't use stored procedures?
No. You are not.
In fact, you are only vulnerable if you use stored procedures together with some kind of privilege-changing statement, such as SECURITY DEFINER, SET ROLE, and SET SESSION AUTHORIZATION.
What are the details of this exploit?
Several external languages which are used as procedural languages support features such as redefining modules, tied variables and other objects at runtime. An attacker, who is an authenticated PostgreSQL user with sufficient rights to create functions (which are available by default), could use this feature to redefine fundamental language components. If done in the same session in which a function in the same language is called by a different ROLE (in particular, a SECURITY DEFINER function is called), this could then cause arbitrary code to be executed with the privileges of that user rather than the attacker's privileges.
This mechanism could be used to circumvent, for example, the use of SET ROLE on connection to restrict user rights. More dangerously, it could be used to hijack a SECURITY DEFINER function and execute whatever "side effect" code the attacker desires.
"Untrusted" languages are not affected because only database superusers can create functions using them, and the untrusted version of a language does not use the same interpreter as the trusted version. If you have both trusted and untrusted versions of a language installed, however, you could still be vulnerable.
How does the 2010-10-05 security update fix this?
It changes PL/perl and PL/tcl to start a separate interpreter for each language for each database ROLE.
Does that break any backwards compatibility?
Not for most users. However, users who were relying on the ability to pass variables or code between database ROLEs or to SECURITY DEFINER functions using shared hashes, modules, etc. may find that they need to modify their application before applying this update. A suggestion is to have all such data passing utilize SECURITY DEFINER functions owned by the same, single non-login ROLE.
As frequently happens, what we see as a security hole a few users probably see as a feature. We apologize to such users for the inconvenience.
What's the difference between a trusted and untrusted language?
"Trusted" procedural languages are ones that any database user with the rights to create functions is allowed to use to create new functions or modify existing functions. "Untrusted" languages are ones which only the database superuser is allowed to use to create new functions, because they may execute code outside of a "safe" database container.
Several languages, including PL/perl, PL/tcl and PL/PHP, can be installed as either Trusted, Untrusted, or both. It has been pointed out that our use of the terms "trusted" and "untrusted" is exactly reversed, but after 13 years such usage would be difficult to change.
I cannot apply the update immediately, or my PL is not patched. How can I work around this vulnerability?
First, three basic precautions lessen your exposure to this and other privilege escalation exploits:
- Obviously, you want to prevent users from executing arbitrary code on your database. In order to take advantage of this exploit, users must be authenticated and able to create new, custom functions.
- If you use SECURITY DEFINER functions, you want to make sure to set the search_path of such functions as detailed in previous security fixes.
- Existing functions and stored procedures should be owned by a different login role than the one associated with your application or web user so that they cannot easily be modified.
An immediate workaround is to remove all rights to create new functions from regular users, which is a good idea in any case for a production database:
REVOKE USAGE ON LANGUAGE procedural_language FROM PUBLIC; example: REVOKE USAGE ON LANGUAGE plruby FROM PUBLIC;
If specific users then need the ability to create functions, they can have that right GRANTed individually.
Do any known exploit scripts exist in the wild for this issue?
Who discovered this vulnerability, then?
PostgreSQL contributor and Perl DBI creator Tim Bunce, while working on improving PL/perl.
I am a maintainer of an external PL and wish to contact someone about patching my PL
Please e-mail email@example.com to discuss this with the PostgreSQL security team.