Mercurial > prosody-modules
comparison mod_http_oauth2/mod_http_oauth2.lua @ 5458:813fe4f76286
mod_http_oauth2: Do minimal validation of private-use URI schemes
Per draft-ietf-oauth-v2-1-08#section-2.3.1
> At a minimum, any private-use URI scheme that doesn't contain a period
> character (.) SHOULD be rejected.
Since this would rule out the OOB URI, which is useful for CLI tools and
such without a built-in http server, it is explicitly allowed.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 16 May 2023 22:18:12 +0200 |
parents | 9156a4754466 |
children | 260a859be86a |
comparison
equal
deleted
inserted
replaced
5457:9156a4754466 | 5458:813fe4f76286 |
---|---|
172 | 172 |
173 local function get_issuer() | 173 local function get_issuer() |
174 return (module:http_url(nil, "/"):gsub("/$", "")); | 174 return (module:http_url(nil, "/"):gsub("/$", "")); |
175 end | 175 end |
176 | 176 |
177 -- Non-standard special redirect URI that has the AS show the authorization | |
178 -- code to the user for them to copy-paste into the client, which can then | |
179 -- continue as if it received it via redirect. | |
180 local oob_uri = "urn:ietf:wg:oauth:2.0:oob"; | |
181 | |
177 local loopbacks = set.new({ "localhost", "127.0.0.1", "::1" }); | 182 local loopbacks = set.new({ "localhost", "127.0.0.1", "::1" }); |
178 local function is_secure_redirect(uri) | 183 local function is_secure_redirect(uri) |
179 local u = url.parse(uri); | 184 local u = url.parse(uri); |
180 return u.scheme ~= "http" or loopbacks:contains(u.host); | 185 return u.scheme ~= "http" or loopbacks:contains(u.host); |
181 end | 186 end |
293 if not ok then | 298 if not ok then |
294 return {status_code = 429}; | 299 return {status_code = 429}; |
295 end | 300 end |
296 | 301 |
297 local redirect_uri = get_redirect_uri(client, params.redirect_uri); | 302 local redirect_uri = get_redirect_uri(client, params.redirect_uri); |
298 if redirect_uri == "urn:ietf:wg:oauth:2.0:oob" then | 303 if redirect_uri == oob_uri then |
299 -- TODO some nicer template page | 304 -- TODO some nicer template page |
300 -- mod_http_errors will set content-type to text/html if it catches this | 305 -- mod_http_errors will set content-type to text/html if it catches this |
301 -- event, if not text/plain is kept for the fallback text. | 306 -- event, if not text/plain is kept for the fallback text. |
302 local response = { status_code = 200; headers = { content_type = "text/plain" } } | 307 local response = { status_code = 200; headers = { content_type = "text/plain" } } |
303 response.body = module:context("*"):fire_event("http-message", { | 308 response.body = module:context("*"):fire_event("http-message", { |
809 local uri = url.parse(redirect_uri); | 814 local uri = url.parse(redirect_uri); |
810 if not uri.scheme then | 815 if not uri.scheme then |
811 return false; -- no relative URLs | 816 return false; -- no relative URLs |
812 end | 817 end |
813 if app_type == "native" then | 818 if app_type == "native" then |
814 return uri.scheme == "http" and loopbacks:contains(uri.host) or uri.scheme ~= "https"; | 819 return uri.scheme == "http" and loopbacks:contains(uri.host) or redirect_uri == oob_uri or uri.scheme:find(".", 1, true) ~= nil; |
815 elseif app_type == "web" then | 820 elseif app_type == "web" then |
816 return uri.scheme == "https" and uri.host == client_uri.host; | 821 return uri.scheme == "https" and uri.host == client_uri.host; |
817 end | 822 end |
818 end | 823 end |
819 | 824 |