Mercurial > prosody-modules
diff mod_http_oauth2/mod_http_oauth2.lua @ 5367:93d445b26063
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.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 25 Apr 2023 19:49:41 +0200 |
parents | db4c66a1d24b |
children | 8b7d97f0ae8a |
line wrap: on
line diff
--- 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