@@ -36,7 +36,6 @@ pub fn set_cookie_cross_site(enabled: bool) {
3636}
3737use chrono:: { Duration , TimeDelta } ;
3838use openid:: Bearer ;
39- use regex:: Regex ;
4039use serde:: Deserialize ;
4140use ulid:: Ulid ;
4241use url:: Url ;
@@ -79,8 +78,8 @@ pub async fn login(
7978 query : web:: Query < RedirectAfterLogin > ,
8079) -> Result < HttpResponse , OIDCError > {
8180 let conn = req. connection_info ( ) . clone ( ) ;
82- let base_url_without_scheme = format ! ( "{}/" , conn. host( ) ) ;
83- if !is_valid_redirect_url ( & base_url_without_scheme , query. redirect . as_str ( ) ) {
81+ let base_url = format ! ( "{}://{}/" , conn . scheme ( ) , conn. host( ) ) ;
82+ if !is_valid_redirect_url ( & base_url , query. redirect . as_str ( ) ) {
8483 return Err ( OIDCError :: BadRequest (
8584 "Bad Request, Invalid Redirect URL!" . to_string ( ) ,
8685 ) ) ;
@@ -167,11 +166,22 @@ pub async fn login(
167166 }
168167}
169168
170- pub async fn logout ( req : HttpRequest , query : web:: Query < RedirectAfterLogin > ) -> HttpResponse {
169+ pub async fn logout (
170+ req : HttpRequest ,
171+ query : web:: Query < RedirectAfterLogin > ,
172+ ) -> Result < HttpResponse , OIDCError > {
171173 let oidc_client = OIDC_CLIENT . get ( ) ;
174+ let conn = req. connection_info ( ) . clone ( ) ;
175+ let base_url = format ! ( "{}://{}/" , conn. scheme( ) , conn. host( ) ) ;
176+
177+ if !is_valid_redirect_url ( & base_url, query. redirect . as_str ( ) ) {
178+ return Err ( OIDCError :: BadRequest (
179+ "Bad Request, Invalid Redirect URL!" . to_string ( ) ,
180+ ) ) ;
181+ }
172182
173183 let Some ( session) = extract_session_key_from_req ( & req) . ok ( ) else {
174- return redirect_to_client ( query. redirect . as_str ( ) , None ) ;
184+ return Ok ( redirect_to_client ( query. redirect . as_str ( ) , None ) ) ;
175185 } ;
176186 let tenant_id = get_tenant_id_from_key ( & session) ;
177187 let user = Users . remove_session ( & session) ;
@@ -185,9 +195,9 @@ pub async fn logout(req: HttpRequest, query: web::Query<RedirectAfterLogin>) ->
185195 ( Some ( username) , Some ( logout_endpoint) )
186196 if Users . is_oauth ( & username, & tenant_id) . unwrap_or_default ( ) =>
187197 {
188- redirect_to_oidc_logout ( logout_endpoint, & query. redirect )
198+ Ok ( redirect_to_oidc_logout ( logout_endpoint, & query. redirect ) )
189199 }
190- _ => redirect_to_client ( query. redirect . as_str ( ) , None ) ,
200+ _ => Ok ( redirect_to_client ( query. redirect . as_str ( ) , None ) ) ,
191201 }
192202}
193203
@@ -643,9 +653,17 @@ impl actix_web::ResponseError for OIDCError {
643653 }
644654}
645655
646- fn is_valid_redirect_url ( base_url_without_scheme : & str , redirect_url : & str ) -> bool {
647- let http_scheme_match_regex = Regex :: new ( r"^(https?://)" ) . unwrap ( ) ;
648- let redirect_url_without_scheme = http_scheme_match_regex. replace ( redirect_url, "" ) ;
649-
650- base_url_without_scheme == redirect_url_without_scheme
656+ fn is_valid_redirect_url ( base_url : & str , redirect_url : & str ) -> bool {
657+ // check if redirect_url is part of allowed origins
658+ if let allowed_origins = & PARSEABLE . options . allow_origins
659+ && ( allowed_origins
660+ . iter ( )
661+ . any ( |url| url. as_str ( ) . eq ( redirect_url) ) )
662+ {
663+ true
664+ }
665+ // if redirect_url is not part of allowed origins, then it must be equal to base url
666+ else {
667+ base_url == redirect_url
668+ }
651669}
0 commit comments