# HG changeset patch # User Kim Alvefur # Date 1682444981 -7200 # Node ID 93d445b260637520aa0075c7dd5606a62286a97a # Parent db4c66a1d24b9987aa538ff34ac7b46e09d83abd mod_http_oauth2: Validate redirect URI depending on application type Per https://openid.net/specs/openid-connect-registration-1_0.html require that web applications use https:// and native applications must use either http://localhost or a custom (non-https) URI. Previous requirement that hostname matches that of client_uri is kept for web applications. diff -r db4c66a1d24b -r 93d445b26063 mod_http_oauth2/mod_http_oauth2.lua --- a/mod_http_oauth2/mod_http_oauth2.lua Tue Apr 25 18:09:08 2023 +0200 +++ b/mod_http_oauth2/mod_http_oauth2.lua Tue Apr 25 19:49:41 2023 +0200 @@ -657,6 +657,7 @@ }; default = { "authorization_code" }; }; + application_type = { type = "string"; enum = { "native"; "web" }; default = "web" }; response_types = { type = "array"; items = { type = "string"; enum = { "code"; "token" } }; default = { "code" } }; client_name = { type = "string" }; client_uri = { type = "string"; format = "uri"; luaPattern = "^https:" }; @@ -677,6 +678,15 @@ }; } +local function redirect_uri_allowed(redirect_uri, client_uri, app_type) + local uri = url.parse(redirect_uri); + if app_type == "native" then + return uri.scheme == "http" and uri.host == "localhost" or uri.scheme ~= "https"; + elseif app_type == "web" then + return uri.scheme == "https" and uri.host == client_uri.host; + end +end + function create_client(client_metadata) if not schema.validate(registration_schema, client_metadata) then return nil, oauth_error("invalid_request", "Failed schema validation."); @@ -695,13 +705,8 @@ end for _, redirect_uri in ipairs(client_metadata.redirect_uris) do - local components = url.parse(redirect_uri); - if not components or not components.scheme then - return nil, oauth_error("invalid_request", "Invalid redirect URI."); - elseif components.scheme == "http" and components.host ~= "localhost" then - return nil, oauth_error("invalid_request", "Insecure redirect URI forbidden (except http://localhost)"); - elseif components.scheme == "https" and components.host ~= client_uri.host then - return nil, oauth_error("invalid_request", "Redirects must use the same hostname as client_uri"); + if not redirect_uri_allowed(redirect_uri, client_uri, client_metadata.application_type) then + return nil, oauth_error("invalid_request", "Invalid, insecure or inappropriate redirect URI."); end end