Re: [PyGreSQL] Plans for Addressing CVE-2018-1058 in PyGreSQL
On Sat, Aug 24, 2019 at 10:05:46PM +0200, Christoph Zwerschke wrote: > Am 16.08.2019 um 19:58 schrieb Shoaib Lari: > > I was wondering if the PyGreSQL community has any plans to address > > PostgreSQL security vulnerability > > https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path. > > Hi Shoaib, thanks for bringing this to our attention. Yes, thanks for mentioning it. > The internal query used by the type cache looks something like this: > > SELECT oid, typname, ... FROM pg_type WHERE oid=%s > > As far as I understand, to make things secure at least what concerns > PyGreSQL, we would need to change that query to: > > SELECT oid, typname, ... FROM pg_catalog.pg_type > WHERE oid OPERATOR(pg.catalog.=) %s Yes, I think > This would make the queries look more ugly and lengthy. Not sure about the > performance impact - maybe it would be even faster because of the explicit > schema name. I agree that they're uglier... > What do others think? Should we make these changes? But I tend to think we should add schema quals, since that's what postgres does. See the commit for that CVE: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=3d2aed664ee8271fd6c721ed0aa10168cda112ea;hp=3bf05e096b9f8375e640c5d7996aa57efd7f240c But it looks like that convention dates back to: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=039cb479884abc28ee494f6cf6c5e7ec26b88fc8 See describe.c https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/bin/psql/describe.c For example \d makes a half dozen queries which look like: [pryzbyj@database ~]$ psql ts -Ec '\d pg_class' * QUERY ** SELECT c.oid, n.nspname, c.relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relname OPERATOR(pg_catalog.~) '^(pg_class)$' AND pg_catalog.pg_table_is_visible(c.oid) ORDER BY 2, 3; ** > Now, if someone was able to do that I think your goose has been cooked > anyway since nearly every query will be affected. ... > I think in practice you need to rely on users not being able to create > objects in the public schema, otherwise you're set for deeper troubles > anyway, no matter how secure your API is. | 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. It's true that one shouldn't create untrusted DB users, but there's a privilege system in place and it's intended to allow users to be at least partially segregated. If postgres/pygres and other projects don't use schema quals, then it's hard to imagine that a typical admin will do so. ___ PyGreSQL mailing list PyGreSQL@Vex.Net https://mail.vex.net/mailman/listinfo/pygresql
Re: [PyGreSQL] Plans for Addressing CVE-2018-1058 in PyGreSQL
Am 16.08.2019 um 19:58 schrieb Shoaib Lari: > I was wondering if the PyGreSQL community has any plans to address > PostgreSQL security vulnerability > https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path. Hi Shoaib, thanks for bringing this to our attention. > Now connect to the postgres database thorough pygresql, and issue a > simple query. > > import pgdb > conn = pgdb.connect(database='postgres') > c = conn.cursor() > c.execute('SELECT 1') > > You will get the following output: > > WARNING: trojan So what's happening here is that the equality operator used in the internal query used by the type cache is called which triggers the warning above because you have overridden the operator in the public schema which takes precedence before the default one in pg_catalog. Now, if someone was able to do that I think your goose has been cooked anyway since nearly every query will be affected. The internal query used by the type cache looks something like this: SELECT oid, typname, ... FROM pg_type WHERE oid=%s As far as I understand, to make things secure at least what concerns PyGreSQL, we would need to change that query to: SELECT oid, typname, ... FROM pg_catalog.pg_type WHERE oid OPERATOR(pg.catalog.=) %s And there's another query for composite types that needs to be fixed in a similar way. We would also need to fix the internal query in the classic pg.py module, which has not only a type cache but also other higher level functions which run internal queries. This would make the queries look more ugly and lengthy. Not sure about the performance impact - maybe it would be even faster because of the explicit schema name. What do others think? Should we make these changes? The guide that you linked to says this: "If you write your queries with specific schema.object form, including objects that exist in the pg_catalog (e.g. calling SELECT pg_catalog.lower('ALICE');), then you are not immediately vulnerable to this issue." But it does not mention operators in this context which are easily overlooked and which will make any query secured that way immediately become very ugly. In practice I think that's not feasible except when all queries are created automatically e.g. by an ORM. I think in practice you need to rely on users not being able to create objects in the public schema, otherwise you're set for deeper troubles anyway, no matter how secure your API is. -- Christoph ___ PyGreSQL mailing list PyGreSQL@Vex.Net https://mail.vex.net/mailman/listinfo/pygresql
[PyGreSQL] Plans for Addressing CVE-2018-1058 in PyGreSQL
Hi, I was wondering if the PyGreSQL community has any plans to address PostgreSQL security vulnerability https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path . Here is a simple test case to reproduce the problem. Create the following two functions in, say, postgres database. CREATE FUNCTION public.evil_eq(oid, integer) RETURNS boolean LANGUAGE plpgsql AS $$ begin raise warning 'trojan'; return oideq($1, $2::oid); end $$; CREATE OPERATOR public.= ( PROCEDURE = public.evil_eq, LEFTARG = oid, RIGHTARG = integer ); Now connect to the postgres database thorough pygresql, and issue a simple query. import pgdb conn = pgdb.connect(database='postgres') c = conn.cursor() c.execute('SELECT 1') You will get the following output: WARNING: trojan . .. << the above is repated 439 times>> >>> Running another query such as 'SELECT * FROM pg_catalog.pg_class LIMIT 1' calls the public.evil_eq() function more than two thousand times. Also, this happens when the first time you run the query after creating the function and connecting. Therefore, the call to OPERATOR(=) is done by PyGreSQL internal queries to get metadata information from the server after initial connect. The Wiki https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path provided instructions for DBAs to mitigate the impact of the vulnerability. Essentially asking that references to the database objects and operators should be fully schema-qualified to prevent an override from a less privileged user. Therefore, I was wondering if the PyGreSQL community has any plans to fully schema-qualify objects and operators for all the internal queries that PyGreSQL issues? Thank you. Shoaib ___ PyGreSQL mailing list PyGreSQL@Vex.Net https://mail.vex.net/mailman/listinfo/pygresql