Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sErKO-0046Zw-Se for pgsql-hackers@arkaria.postgresql.org; Wed, 05 Jun 2024 14:09:26 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sErKO-008w7j-Sl for pgsql-hackers@arkaria.postgresql.org; Wed, 05 Jun 2024 14:09:24 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sErKO-008w7b-Ip for pgsql-hackers@lists.postgresql.org; Wed, 05 Jun 2024 14:09:24 +0000 Received: from mail-ej1-x62b.google.com ([2a00:1450:4864:20::62b]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sErKL-00084P-Q5 for pgsql-hackers@postgresql.org; Wed, 05 Jun 2024 14:09:23 +0000 Received: by mail-ej1-x62b.google.com with SMTP id a640c23a62f3a-a68fc86acfaso162633766b.1 for ; Wed, 05 Jun 2024 07:09:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1717596561; x=1718201361; darn=postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=jlgsrdLwuUYWwt9L2y+i+PqwaHyyjI1tTsxFlS4dCbI=; b=XjC7bqiQoXO4z8xS1ZFLwTz5yyhIpV8gZUXa8v1i+v8/af0HFUQyUDfRHbR2J7r5Bi Suwc/uydXRntn+j9KH83GAvOi52BPkE57oeu4Z9jZ6FB0uWczYnx2u6Q1yaYW3YFv/is 8780i2H+7+UBWFrdxCmVVcY9bLde/+A97S6TWOAF4vo63hElOa4HXs1oCDdVRiow3G/4 HpcX0haSegIEzEc93EkM/0JQmdM62IROgefpnJDH2Hd3XKB1FOA/jZxnZFFzS6RDAnV9 9ttUa1ixAHmWVl0+yXILIRq69vLQAn5iNKllG8KXKNaOrZEZ/aa5+B5swOIxfIztb0nZ 0gNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717596561; x=1718201361; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=jlgsrdLwuUYWwt9L2y+i+PqwaHyyjI1tTsxFlS4dCbI=; b=NTmayuYn6xFGiox0p5/yOMcudA2afcaSbqE/SU7+Ek2jMM03suuinTdZgMRwzYMPPc mjP8/+yP8jV3h5mMvOxrnEOJkqB/0ZfEcMMdj7XC0fRYVoYshxnzRbUqhfJ1ZQQb6W01 5vLZbIfuPq/UaOPM5mXew8Lf6SN/Dza+IVde36fvfPlE8+1Eo0R6rHXl6RXfE/2R5HTW g4VnyZXJTuyokE9sf6o981NpLdgoOUmMtOJReKB9x4cctKSYj3vhtBLFlB5281Ooq+Y3 BAM/bsBid/uU6Py+oA70uqxUdniXiX8nLwwssLvyZzPj00P0arHa/oWLO9k6eP0fp7Jo dtvQ== X-Gm-Message-State: AOJu0Ywz9PvAjXqjNW0AObRWliKg0Qc8iwmDjJm801A42RZHJrj2bu38 kZdEWgPowzwlcfEbwlrfbrq+wE0vnNTR32dh9/i2HUc4O1BFdCxgPKmdm/2oupa9NPgOFQCyEoi spP/Efwka6ke2LniJN3lsLjuYJzw= X-Google-Smtp-Source: AGHT+IH/H88WcdUmA+1PNdIyAZMZKofXON5dvkyVlCFD7BH/LdGYQ/9xx4ms2W/rxovc8QPbvX3bqYqv8GNKC6Pu2LY= X-Received: by 2002:a17:906:11d9:b0:a68:5b05:bdea with SMTP id a640c23a62f3a-a699d8632d0mr191896566b.37.1717596561018; Wed, 05 Jun 2024 07:09:21 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Marco Slot Date: Wed, 5 Jun 2024 16:09:08 +0200 Message-ID: Subject: Re: Extension security improvement: Add support for extensions with an owned schema To: Jelte Fennema-Nio Cc: PostgreSQL-development Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Sun, Jun 2, 2024, 02:08 Jelte Fennema-Nio wrote: > This patch adds a new "owned_schema" option to the extension control > file that can be set to true to indicate that this extension wants to > own the schema in which it is installed. Huge +1 Many managed PostgreSQL services block superuser access, but provide a way for users to trigger a create/alter extension as superuser. There have been various extensions whose SQL scripts can be tricked into calling a function that was pre-created in the extension schema. This is usually done by finding an unqualified call to a pg_catalog function/operator, and overloading it with one whose arguments types are a closer match for the provided values, which then takes precedence regardless of search_path order. The custom function can then do something like "alter user foo superuser". The sequence of steps assumes the user already has some kind of admin role and is gaining superuser access to their own database server. However, the superuser implicitly has shell access, so it gives attackers an additional set of tools to poke around in the managed service. For instance, they can change the way the machine responds to control plane requests, which can sometimes trigger further escalations. In addition, many applications use the relatively privileged default user, which means SQL injection issues can also escalate into superuser access and beyond. There are some static analysis tools like https://github.com/timescale/pgspot that address this issue, though it seems like a totally unnecessary hole. Using schema = pg_catalog, relocatable = false, and doing an explicit create schema (without "if not exists") plugs the hole by effectively disabling extension schemas. For extensions I'm involved in, I consider this to be a hard requirement. I think Jelte's solution is preferable going forward, because it preserves the flexibility that extension schemas were meant to provide, and makes the potential hazards of reusing a schema more explicit. cheers, Marco