add: log error when db-schemas config contain restricted schemas

We don't allow accessing schemas "pg_catalog" and "information_schema".
Instead of silently failing requests on these schemas, this now adds
logging an error on startup when these schemas are found in `db-schemas`
config.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
This commit is contained in:
Taimoor Zaeem
2025-12-11 14:28:08 -05:00
committed by Steve Chavez
parent c232e97f80
commit abad47ff1b
5 changed files with 40 additions and 2 deletions
+4
View File
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. From versio
## Unreleased
### Added
- Log error when `db-schemas` config contains schema `pg_catalog` or `information_schema` by @taimoorzaeem in #4359
### Fixed
- Fix misleading logs on unsupported PostgreSQL versions by @taimoorzaeem in #4519
+4
View File
@@ -5,6 +5,10 @@ Schemas
PostgREST can expose a single or multiple schema's tables, views and functions. The :ref:`active database role <roles>` must have the usage privilege on the schemas to access them.
.. important::
``pg_catalog`` and ``information_schema`` are not allowed in :ref:`db-schemas`. This is done to prevent leaking sensitive information and hence they cannot be accessed directly. If you wish to expose objects of these schemas, expose another schema that contains wrapper views or functions over ``pg_catalog`` or ``information_schema`` objects.
Single schema
-------------
+13 -2
View File
@@ -274,8 +274,7 @@ parser optPath env dbSettings roleSettings roleIsolationLvl =
<*> (fromMaybe True <$> optBool "db-prepared-statements")
<*> (fmap toQi <$> optWithAlias (optString "db-root-spec")
(optString "root-spec"))
<*> (fromList . maybe ["public"] splitOnCommas <$> optWithAlias (optString "db-schemas")
(optString "db-schema"))
<*> parseDbSchemas "db-schemas" "db-schema"
<*> (fromMaybe True <$> optBool "db-config")
<*> (fmap toQi <$> optString "db-pre-config")
<*> parseTxEnd "db-tx-end" snd
@@ -329,6 +328,18 @@ parser optPath env dbSettings roleSettings roleIsolationLvl =
Just asp | asp == serverPort -> fail "admin-server-port cannot be the same as server-port"
| otherwise -> pure $ Just asp
parseDbSchemas :: C.Key -> C.Key -> C.Parser C.Config (NonEmpty Text)
parseDbSchemas k al =
optWithAlias (optString k) (optString al) >>= \case
Nothing -> pure $ fromList ["public"]
Just s
| "pg_catalog" `elem` schemas -> fail (errMsg "pg_catalog")
| "information_schema" `elem` schemas -> fail (errMsg "information_schema")
| otherwise -> pure $ fromList schemas
where
schemas = splitOnCommas s
errMsg x = ("db-schemas does not allow schema: '" <> x <> "'")
parseSocketFileMode :: C.Key -> C.Parser C.Config FileMode
parseSocketFileMode k =
optString k >>= \case
+4
View File
@@ -237,3 +237,7 @@ specialhostvalues:
- '*6'
- '!6'
- '*'
restrictedschemas:
- 'pg_catalog'
- 'information_schema'
+15
View File
@@ -286,6 +286,21 @@ def test_jwt_secret_min_length(defaultenv):
assert "The JWT secret must be at least 32 characters long." in error
@pytest.mark.parametrize("restricted_schema", FIXTURES["restrictedschemas"])
def test_restricted_db_schemas(restricted_schema, defaultenv):
"Should print error when db-schemas config contain pg_catalog or information_schema"
# test when single schema is given in db-schemas
env = {**defaultenv, "PGRST_DB_SCHEMAS": restricted_schema}
error = cli(["--dump-config"], env=env, expect_error=True)
assert f"db-schemas does not allow schema: '{restricted_schema}'" in error
# test when multiple schemas are given in db-schemas
env = {**defaultenv, "PGRST_DB_SCHEMAS": f"public, {restricted_schema}"}
error = cli(["--dump-config"], env=env, expect_error=True)
assert f"db-schemas does not allow schema: '{restricted_schema}'" in error
# TODO: Improve readability of "--ready" healthcheck tests
@pytest.mark.parametrize("host", ["127.0.0.1", "::1"], ids=["IPv4", "IPv6"])
def test_cli_ready_flag_success(host, defaultenv):