Thread: dump/restore problem due to CVE-2018-1058 (9.5.12)

dump/restore problem due to CVE-2018-1058 (9.5.12)

From
Rory Campbell-Lange
Date:
Hi

Following an upgrade to 9.5.12, we cannot restore some of our databases
due to a schema qualification issue introduced in the new postgres
version of pg_dump.

Specifically, the problem line is the addition of :

    SELECT pg_catalog.set_config('search_path', '', false);

to the header of the pg_dump output.

As a result, pg_restore now fails because we have some table constraints
that use functions which do not use public schema qualified table/column
references. 

(I'm aware that the reasons behind the change made to the dump format
due to CVE-2018-1058 are set out here:
https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path)

We intend to change the schema qualifications in the check constraints
to work around this issue.

However I can't help but feel forcing the search_path to '' in pg_dump,
without a way that we can find for overriding it via setting, for
example, libpq environmental variables, is a rather odd constraint, as
when we load the backup as the postgres superuser. (I realise I can pipe
through sed or do something similar to fix this issue, but I don't see
why that is necessary).

Additionally we sometimes use search_path manipulations +
temporary_schema.function to test functions in production environments.
Having to qualify the schema of objects seems a retrogressive step, but
perhaps our usage is peculiar in this way.

Also, in a coding environment where object.attribute masking is a
feature of the language, as it is in python, this change seems obtuse.
My function in schema x can still mask a function in another schema y,
so the problem of function masking (if it is a problem) still exists.

Finally, if the point of the change was to make it less likely to allow
<general_schema>.<function> attacks then the mechanisms are already in
place to avoid that, namely the steps mentioned in the url above: 

    ALTER ROLE username SET search_path = "$user";

and

    removing the default search_path setting postgresql.conf

and, most importantly

    REVOKE CREATE ON SCHEMA public FROM PUBLIC;

The permissions would therefore be at a policy level rather than what
seems like a bit of a cludge in pg_dump's output.

My apologies if I have missed the subtlety of the solution to the
problem, but allowing a normal user to write functions to public reminds
me of perl's Tom Christensen's famous reference to a "victimless crime".
In any event it probably *would* be good to not allow non-superusers to
mask a pg_catalog (or perhaps any other schema) function unless they
have a specific permission to do so. That is something I feel would be a
more useful solution to the security issue than only fiddling with the
public schema.

Thanks for any comments.
    
Regards
Rory


Re: dump/restore problem due to CVE-2018-1058 (9.5.12)

From
Adrian Klaver
Date:
On 04/07/2018 12:27 PM, Rory Campbell-Lange wrote:
> Hi
> 
> Following an upgrade to 9.5.12, we cannot restore some of our databases
> due to a schema qualification issue introduced in the new postgres
> version of pg_dump.
> 
> Specifically, the problem line is the addition of :
> 
>      SELECT pg_catalog.set_config('search_path', '', false);
> 
> to the header of the pg_dump output.
> 
> As a result, pg_restore now fails because we have some table constraints
> that use functions which do not use public schema qualified table/column
> references.
> 
> (I'm aware that the reasons behind the change made to the dump format
> due to CVE-2018-1058 are set out here:
> https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path)
> 

> Additionally we sometimes use search_path manipulations +
> temporary_schema.function to test functions in production environments.
> Having to qualify the schema of objects seems a retrogressive step, but
> perhaps our usage is peculiar in this way.

AFAIK you can still do that or did I miss something?

> 
> Also, in a coding environment where object.attribute masking is a
> feature of the language, as it is in python, this change seems obtuse.
> My function in schema x can still mask a function in another schema y,
> so the problem of function masking (if it is a problem) still exists.

Are talking Python external or internal to Postgres?

If internal, then plpythonu is an untrusted language and can only be 
used by a superuser. If you are a superuser then there is host of other 
things you could do to compromise security as well.


> 
> Thanks for any comments.
>      
> Regards
> Rory
> 
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com


Re: dump/restore problem due to CVE-2018-1058 (9.5.12)

From
Rory Campbell-Lange
Date:
On 07/04/18, Adrian Klaver (adrian.klaver@aklaver.com) wrote:
> > (I'm aware that the reasons behind the change made to the dump format
> > due to CVE-2018-1058 are set out here:
> > https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path)
> > 
> 
> > Additionally we sometimes use search_path manipulations +
> > temporary_schema.function to test functions in production environments.
> > Having to qualify the schema of objects seems a retrogressive step, but
> > perhaps our usage is peculiar in this way.
> 
> AFAIK you can still do that or did I miss something?

Yes, you can still do this. Howevever if my function in schema x can
still mask the function in schema y I suggest the security issue still
exists (as it doesn't refer, at least in the title, to only the 'public'
schema):

    https://nvd.nist.gov/vuln/detail/CVE-2018-1058#vulnCurrentDescriptionTitle
    A flaw was found in the way Postgresql allowed a user to modify the
    behavior of a query for other users. An attacker with a user account
    could use this flaw to execute code with the permissions of superuser in
    the database. Versions 9.3 through 10 are affected.

So if in my database the default search path is x, y, z this "flaw"
still exists.

> > Also, in a coding environment where object.attribute masking is a
> > feature of the language, as it is in python, this change seems obtuse.
> > My function in schema x can still mask a function in another schema y,
> > so the problem of function masking (if it is a problem) still exists.
> 
> Are talking Python external or internal to Postgres?

I'm talking about how schema.function works in general in postgresql,
how useful that is, and how that is similar to other languages (like
python).

My further suggestion, admittedly from a naive perspective, is that the
solution to this problem is inadequate and partial, and that other
techniques should be used to solve it, such as making the masking of
functions in pg_catalog a new user permission or changing the default
search path of postgres superusers to prepend pg_catalog.

It still isn't clear to me why the output from pg_dump has a search_path
set to ''. That seems to be security through obscurity.

Thanks very much for your comments
Rory


Re: dump/restore problem due to CVE-2018-1058 (9.5.12)

From
Adrian Klaver
Date:
On 04/08/2018 03:40 AM, Rory Campbell-Lange wrote:
> On 07/04/18, Adrian Klaver (adrian.klaver@aklaver.com) wrote:
>>> (I'm aware that the reasons behind the change made to the dump format
>>> due to CVE-2018-1058 are set out here:
>>> https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path)
>>>
>>
>>> Additionally we sometimes use search_path manipulations +
>>> temporary_schema.function to test functions in production environments.
>>> Having to qualify the schema of objects seems a retrogressive step, but
>>> perhaps our usage is peculiar in this way.
>>
>> AFAIK you can still do that or did I miss something?
> 
> Yes, you can still do this. Howevever if my function in schema x can
> still mask the function in schema y I suggest the security issue still
> exists (as it doesn't refer, at least in the title, to only the 'public'
> schema):
> 
>      https://nvd.nist.gov/vuln/detail/CVE-2018-1058#vulnCurrentDescriptionTitle
>      A flaw was found in the way Postgresql allowed a user to modify the
>      behavior of a query for other users. An attacker with a user account
>      could use this flaw to execute code with the permissions of superuser in
>      the database. Versions 9.3 through 10 are affected.
> 
> So if in my database the default search path is x, y, z this "flaw"
> still exists.

The above refers to the general case and is correct in that regard. The 
Wiki link you shared in your first post details the case that puts you 
at most risk:

https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path 


Background: What is CVE-2018-1058?

"
The PostgreSQL 7.3 release introduced "schemas," which allowed users to 
create objects (e.g. tables, functions, etc.) in separate namespaces. 
When a user creates a database, by default, PostgreSQL creates a schema 
called public where, by default, all new objects (e.g. tables, 
functions) are created.

...

Without adjusting the configuration or access control settings, any user 
that can connect to a database can also create objects in the public 
schema for that database. A PostgreSQL administrator can grant and 
revoke permissions for a user to both use and/or create objects within a 
particular schema.

Schemas allow users to namespace objects, so objects of the same name 
can exist in different schemas in the same database. If there are 
objects with the same name in different schemas and the specific 
schema/object pair is not specified (i.e. schema.object), PostgreSQL 
decides which object to use based on the search_path setting. The 
search_path setting specifies the order the schemas are searched when 
looking for an object. The default value for search_path is $user,public 
where $user refers to the name of the user connected (which can be 
determined by executing SELECT SESSION_USER;).
"

The Problem: CVE-2018-1058

"
The problem described in CVE-2018-1058 centers around the default 
"public" schema and how PostgreSQL uses the search_path setting.
"

Boiled down it means that out of the box Postgres allows any user to 
create objects in the 'public' schema and the default search_path 
includes that schema. This allows an unprivileged user to create a 
masking function, though the ability to mask is dependent on other 
factors as shown in the example in 'The Problem' section above.

You are correct in that this can happen between other schemas as well. 
The difference is that setting up those schemas is done by the DBA not 
the project and so it is up to the DBA to enforce security. What it 
comes down to is that the release was not a fix as much as a heads up:

"The purpose of the release was to address CVE-2018-1058, which 
describes how a user can create like-named objects in different schemas 
that can change the behavior of other users' queries and cause 
unexpected or malicious behavior, also known as a "trojan-horse" attack. 
Most of this release centered around added documentation that described 
the issue and how to take steps to mitigate the impact on PostgreSQL 
databases. "

More comments below.

> 
>>> Also, in a coding environment where object.attribute masking is a
>>> feature of the language, as it is in python, this change seems obtuse.
>>> My function in schema x can still mask a function in another schema y,
>>> so the problem of function masking (if it is a problem) still exists.
>>
>> Are talking Python external or internal to Postgres?
> 
> I'm talking about how schema.function works in general in postgresql,
> how useful that is, and how that is similar to other languages (like
> python).
> 
> My further suggestion, admittedly from a naive perspective, is that the
> solution to this problem is inadequate and partial, and that other
> techniques should be used to solve it, such as making the masking of
> functions in pg_catalog a new user permission or changing the default
> search path of postgres superusers to prepend pg_catalog.
> 
> It still isn't clear to me why the output from pg_dump has a search_path
> set to ''. That seems to be security through obscurity.

I see it more as a way to flag those instances that fail the 
recommendations in the Wiki article e.g. :

"As a result, pg_restore now fails because we have some table 
constraints that use functions which do not use public schema qualified 
table/column references. "

> 
> Thanks very much for your comments
> Rory
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com


Re: dump/restore problem due to CVE-2018-1058 (9.5.12)

From
Rory Campbell-Lange
Date:
Thanks for your comprehensive response, Adrian.

On 08/04/18, Adrian Klaver (adrian.klaver@aklaver.com) wrote:
> On 04/08/2018 03:40 AM, Rory Campbell-Lange wrote:
> > On 07/04/18, Adrian Klaver (adrian.klaver@aklaver.com) wrote:
> > > > (I'm aware that the reasons behind the change made to the dump format
> > > > due to CVE-2018-1058 are set out here:
> > > > https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path)

> > So if in my database the default search path is x, y, z this "flaw"
> > still exists.
> 
> The above refers to the general case and is correct in that regard. The Wiki
> link you shared in your first post details the case that puts you at most
> risk:
> 
> https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path

...

> Without adjusting the configuration or access control settings, any user
> that can connect to a database can also create objects in the public schema
> for that database.

...

> The Problem: CVE-2018-1058
> 
> "
> The problem described in CVE-2018-1058 centers around the default "public"
> schema and how PostgreSQL uses the search_path setting.
> "
> 
> Boiled down it means that out of the box Postgres allows any user to create
> objects in the 'public' schema and the default search_path includes that
> schema. This allows an unprivileged user to create a masking function,
> though the ability to mask is dependent on other factors as shown in the
> example in 'The Problem' section above.
> 
> You are correct in that this can happen between other schemas as well. The
> difference is that setting up those schemas is done by the DBA not the
> project and so it is up to the DBA to enforce security. What it comes down
> to is that the release was not a fix as much as a heads up:
> 
> "The purpose of the release was to address CVE-2018-1058, which describes
> how a user can create like-named objects in different schemas that can
> change the behavior of other users' queries and cause unexpected or
> malicious behavior, also known as a "trojan-horse" attack. Most of this
> release centered around added documentation that described the issue and how
> to take steps to mitigate the impact on PostgreSQL databases. "

Thank you for setting out the rationale behind the changes so clearly.

> > It still isn't clear to me why the output from pg_dump has a search_path
> > set to ''. That seems to be security through obscurity.
> 
> I see it more as a way to flag those instances that fail the recommendations
> in the Wiki article e.g. :
> 
> "As a result, pg_restore now fails because we have some table constraints
> that use functions which do not use public schema qualified table/column
> references. "

Fair enough. It is however a tedious problem to resolve in a large
code base and it would be cool to have a new "--set-search-path"
option to pg_dump to override it.

Thanks again
Rory


Re: dump/restore problem due to CVE-2018-1058 (9.5.12)

From
Adrian Klaver
Date:
On 04/08/2018 11:01 AM, Rory Campbell-Lange wrote:
> Thanks for your comprehensive response, Adrian.

> 
> Fair enough. It is however a tedious problem to resolve in a large
> code base and it would be cool to have a new "--set-search-path"
> option to pg_dump to override it.

 From other posts that covered similar ground I would say other people 
would agree. I am guessing the response you will get from those that can 
make the changes is that would be just delaying the inevitable. You can 
always ask though:)

> 
> Thanks again
> Rory
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com