fix: jwt-aud config not failing when set to invalid URI (#4140)

The `jwt-aud` config was not validated when containing ':'
character according to RFC 3986. This fix validates it and
fails at startup if it is invalid.
This commit is contained in:
Taimoor Zaeem
2025-06-16 15:40:47 -05:00
committed by GitHub
parent a2892ab1dd
commit c318d46469
4 changed files with 34 additions and 8 deletions
+1
View File
@@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed ### Fixed
- Fix `max-affected` preference not failing with RPC when `handling=strict` by @taimoorzaeem in #4100 - Fix `max-affected` preference not failing with RPC when `handling=strict` by @taimoorzaeem in #4100
- Fix `jwt-aud` config not failing when set to an invalid URI by @taimoorzaeem in #4132
- Fix a property definition's type in OpenAPI not showing the correct base type of a recursive domain by @laurenceisla in #4136 - Fix a property definition's type in OpenAPI not showing the correct base type of a recursive domain by @laurenceisla in #4136
- Fix regression that makes full-text search not work on domain types based on `tsvector` by @laurenceisla in #4135 - Fix regression that makes full-text search not work on domain types based on `tsvector` by @laurenceisla in #4135
+16 -2
View File
@@ -48,7 +48,7 @@ import Data.List.NonEmpty (fromList, toList)
import Data.Maybe (fromJust) import Data.Maybe (fromJust)
import Data.Scientific (floatingOrInteger) import Data.Scientific (floatingOrInteger)
import Jose.Jwk (Jwk, JwkSet) import Jose.Jwk (Jwk, JwkSet)
import Network.URI (escapeURIString, import Network.URI (escapeURIString, isURI,
isUnescapedInURIComponent) isUnescapedInURIComponent)
import Numeric (readOct, showOct) import Numeric (readOct, showOct)
import System.Environment (getEnvironment) import System.Environment (getEnvironment)
@@ -281,7 +281,7 @@ parser optPath env dbSettings roleSettings roleIsolationLvl =
<*> (fromMaybe "postgresql://" <$> optString "db-uri") <*> (fromMaybe "postgresql://" <$> optString "db-uri")
<*> pure optPath <*> pure optPath
<*> pure Nothing <*> pure Nothing
<*> optString "jwt-aud" <*> optStringOrURI "jwt-aud"
<*> parseRoleClaimKey "jwt-role-claim-key" "role-claim-key" <*> parseRoleClaimKey "jwt-role-claim-key" "role-claim-key"
<*> (fmap encodeUtf8 <$> optString "jwt-secret") <*> (fmap encodeUtf8 <$> optString "jwt-secret")
<*> (fromMaybe False <$> optWithAlias <*> (fromMaybe False <$> optWithAlias
@@ -407,6 +407,20 @@ parser optPath env dbSettings roleSettings roleIsolationLvl =
optStringEmptyable :: C.Key -> C.Parser C.Config (Maybe Text) optStringEmptyable :: C.Key -> C.Parser C.Config (Maybe Text)
optStringEmptyable k = overrideFromDbOrEnvironment C.optional k coerceText optStringEmptyable k = overrideFromDbOrEnvironment C.optional k coerceText
optStringOrURI :: C.Key -> C.Parser C.Config (Maybe Text)
optStringOrURI k = do
stringOrURI <- mfilter (/= "") <$> overrideFromDbOrEnvironment C.optional k coerceText
-- If the string contains ':' then it should
-- be a valid URI according to RFC 3986
case stringOrURI of
Just s -> if T.isInfixOf ":" s then validateURI s else return (Just s)
Nothing -> return Nothing
where
validateURI :: Text -> C.Parser C.Config (Maybe Text)
validateURI s = if isURI (T.unpack s)
then return $ Just s
else fail "jwt-aud should be a string or a valid URI"
optInt :: (Read i, Integral i) => C.Key -> C.Parser C.Config (Maybe i) optInt :: (Read i, Integral i) => C.Key -> C.Parser C.Config (Maybe i)
optInt k = join <$> overrideFromDbOrEnvironment C.optional k coerceInt optInt k = join <$> overrideFromDbOrEnvironment C.optional k coerceInt
+5 -6
View File
@@ -41,12 +41,11 @@ cli:
use_defaultenv: true use_defaultenv: true
env: env:
PGRST_SERVER_UNIX_SOCKET_MODE: '778' PGRST_SERVER_UNIX_SOCKET_MODE: '778'
# TODO: Bug needs to be fixed - name: invalid jwt-aud
# - name: invalid jwt-aud expect: error
# expect: error use_defaultenv: true
# use_defaultenv: true env:
# env: PGRST_JWT_AUD: 'http://%%localhorst.invalid'
# PGRST_JWT_AUD: 'htp:/@@localhorst.invalid'
- name: invalid log-level - name: invalid log-level
expect: error expect: error
use_defaultenv: true use_defaultenv: true
+12
View File
@@ -277,3 +277,15 @@ def test_schema_cache_snapshot(baseenv, key, snapshot_yaml):
Dumper=yaml.SafeDumper if key == "dbTimezones" else ExtraNewLinesDumper, Dumper=yaml.SafeDumper if key == "dbTimezones" else ExtraNewLinesDumper,
) )
assert formatted == snapshot_yaml assert formatted == snapshot_yaml
def test_jwt_aud_config_set_to_invalid_uri(defaultenv):
"PostgREST should exit with an error message in output if jwt-aud config is set to an invalid URI"
env = {
**defaultenv,
"PGRST_JWT_AUD": "foo://%%$$^^.com",
}
with pytest.raises(PostgrestError):
dump = cli(["--dump-config"], env=env).split("\n")
assert "jwt-aud should be a string or a valid URI" in dump