@@ -26,6 +26,7 @@ use actix_web::{
26
26
} ;
27
27
use http:: StatusCode ;
28
28
use openid:: { Options , Token , Userinfo } ;
29
+ use regex:: Regex ;
29
30
use serde:: Deserialize ;
30
31
use ulid:: Ulid ;
31
32
use url:: Url ;
@@ -64,10 +65,14 @@ pub async fn login(
64
65
query : web:: Query < RedirectAfterLogin > ,
65
66
) -> Result < HttpResponse , OIDCError > {
66
67
let conn = req. connection_info ( ) . clone ( ) ;
67
- let base_url = format ! ( "{}://{}/" , conn. scheme( ) , conn. host( ) ) ;
68
- if !base_url. eq ( query. redirect . as_str ( ) ) {
69
- return Err ( OIDCError :: BadRequest ) ;
68
+ let base_url_without_scheme = format ! ( "{}/" , conn. host( ) ) ;
69
+
70
+ if !is_valid_redirect_url ( & base_url_without_scheme, query. redirect . as_str ( ) ) {
71
+ return Err ( OIDCError :: BadRequest (
72
+ "Bad Request, Invalid Redirect URL!" . to_string ( ) ,
73
+ ) ) ;
70
74
}
75
+
71
76
let oidc_client = req. app_data :: < Data < DiscoveredClient > > ( ) ;
72
77
let session_key = extract_session_key_from_req ( & req) . ok ( ) ;
73
78
let ( session_key, oidc_client) = match ( session_key, oidc_client) {
@@ -99,7 +104,7 @@ pub async fn login(
99
104
[ user_cookie, session_cookie] ,
100
105
) )
101
106
}
102
- _ => Err ( OIDCError :: BadRequest ) ,
107
+ _ => Err ( OIDCError :: BadRequest ( "Bad Request" . to_string ( ) ) ) ,
103
108
} ,
104
109
// if it's a valid active session, just redirect back
105
110
key @ SessionKey :: SessionId ( _) => {
@@ -367,8 +372,8 @@ pub enum OIDCError {
367
372
ObjectStorageError ( #[ from] ObjectStorageError ) ,
368
373
#[ error( "{0}" ) ]
369
374
Serde ( #[ from] serde_json:: Error ) ,
370
- #[ error( "Bad Request " ) ]
371
- BadRequest ,
375
+ #[ error( "{0} " ) ]
376
+ BadRequest ( String ) ,
372
377
#[ error( "Unauthorized" ) ]
373
378
Unauthorized ,
374
379
}
@@ -378,7 +383,7 @@ impl actix_web::ResponseError for OIDCError {
378
383
match self {
379
384
Self :: ObjectStorageError ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
380
385
Self :: Serde ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
381
- Self :: BadRequest => StatusCode :: BAD_REQUEST ,
386
+ Self :: BadRequest ( _ ) => StatusCode :: BAD_REQUEST ,
382
387
Self :: Unauthorized => StatusCode :: UNAUTHORIZED ,
383
388
}
384
389
}
@@ -389,3 +394,10 @@ impl actix_web::ResponseError for OIDCError {
389
394
. body ( self . to_string ( ) )
390
395
}
391
396
}
397
+
398
+ fn is_valid_redirect_url ( base_url_without_scheme : & str , redirect_url : & str ) -> bool {
399
+ let http_scheme_match_regex = Regex :: new ( r"^(https?://)" ) . unwrap ( ) ;
400
+ let redirect_url_without_scheme = http_scheme_match_regex. replace ( redirect_url, "" ) ;
401
+
402
+ base_url_without_scheme == redirect_url_without_scheme
403
+ }
0 commit comments