comparison mod_http_oauth2/mod_http_oauth2.lua @ 5796:93d6e9026c1b

mod_http_oauth2: Do not enforce PKCE on Device and OOB flows PKCE does not appear to be used with the Device flow. I have found no mention of any interaction between those standards. Since no data is delivered via redirects in these cases, PKCE may not serve any purpose. This is mostly a problem because we reuse the authorization code to implement the Device and OOB flows.
author Kim Alvefur <zash@zash.se>
date Fri, 15 Dec 2023 12:10:07 +0100
parents 72799c330986
children 03477980f1a9
comparison
equal deleted inserted replaced
5795:5533c577dd02 5796:93d6e9026c1b
398 if not request_host or request_host ~= module.host then 398 if not request_host or request_host ~= module.host then
399 return oauth_error("invalid_request", "invalid JID"); 399 return oauth_error("invalid_request", "invalid JID");
400 end 400 end
401 local granted_scopes, granted_role = filter_scopes(request_username, params.scope); 401 local granted_scopes, granted_role = filter_scopes(request_username, params.scope);
402 402
403 if pkce_required and not params.code_challenge then 403 local redirect_uri = get_redirect_uri(client, params.redirect_uri);
404
405 if pkce_required and not params.code_challenge and redirect_uri ~= device_uri and redirect_uri ~= oob_uri then
404 return oauth_error("invalid_request", "PKCE required"); 406 return oauth_error("invalid_request", "PKCE required");
405 end 407 end
406 408
407 local prefix = "authorization_code:"; 409 local prefix = "authorization_code:";
408 local code = id.medium(); 410 local code = id.medium();
409 if params.redirect_uri == device_uri then 411 if redirect_uri == device_uri then
410 local is_device, device_state = verify_device_token(params.state); 412 local is_device, device_state = verify_device_token(params.state);
411 if is_device then 413 if is_device then
412 -- reconstruct the device_code 414 -- reconstruct the device_code
413 prefix = "device_code:"; 415 prefix = "device_code:";
414 code = b64url(hashes.hmac_sha256(verification_key, device_state.user_code)); 416 code = b64url(hashes.hmac_sha256(verification_key, device_state.user_code));
427 }); 429 });
428 if not ok then 430 if not ok then
429 return oauth_error("temporarily_unavailable"); 431 return oauth_error("temporarily_unavailable");
430 end 432 end
431 433
432 local redirect_uri = get_redirect_uri(client, params.redirect_uri);
433 if redirect_uri == oob_uri then 434 if redirect_uri == oob_uri then
434 return render_page(templates.oob, { client = client; authorization_code = code }, true); 435 return render_page(templates.oob, { client = client; authorization_code = code }, true);
435 elseif redirect_uri == device_uri then 436 elseif redirect_uri == device_uri then
436 return render_page(templates.device, { client = client }, true); 437 return render_page(templates.device, { client = client }, true);
437 elseif not redirect_uri then 438 elseif not redirect_uri then
753 -- appending the error information to the redirect_uri and sending the 754 -- appending the error information to the redirect_uri and sending the
754 -- redirect to the user-agent. In some cases we can't do this, e.g. if 755 -- redirect to the user-agent. In some cases we can't do this, e.g. if
755 -- the redirect_uri is missing or invalid. In those cases, we render an 756 -- the redirect_uri is missing or invalid. In those cases, we render an
756 -- error directly to the user-agent. 757 -- error directly to the user-agent.
757 local function error_response(request, redirect_uri, err) 758 local function error_response(request, redirect_uri, err)
758 if not redirect_uri or redirect_uri == oob_uri then 759 if not redirect_uri or redirect_uri == oob_uri or redirect_uri == device_uri then
759 return render_error(err); 760 return render_error(err);
760 end 761 end
761 local q = strict_formdecode(request.url.query); 762 local q = strict_formdecode(request.url.query);
762 local redirect_query = url.parse(redirect_uri); 763 local redirect_query = url.parse(redirect_uri);
763 local sep = redirect_query.query and "&" or "?"; 764 local sep = redirect_query.query and "&" or "?";