@@ -43,6 +43,7 @@ import { UserService } from "./user-service";
4343import { WorkspaceService } from "../workspace/workspace-service" ;
4444import { runWithSubjectId } from "../util/request-context" ;
4545import { SubjectId } from "../auth/subject-id" ;
46+ import { getFeatureFlagEnableStrictAuthorizeReturnTo } from "../util/featureflags" ;
4647
4748export const ServerFactory = Symbol ( "ServerFactory" ) ;
4849export type ServerFactory = ( ) => GitpodServerImpl ;
@@ -240,8 +241,16 @@ export class UserController {
240241 res . sendStatus ( 403 ) ;
241242 return ;
242243 }
243- this . ensureSafeReturnToParamForAuthorize ( req ) ;
244- this . authenticator . authorize ( req , res , next ) . catch ( ( err ) => log . error ( "authenticator.authorize" , err ) ) ;
244+ this . ensureSafeReturnToParam ( req ) ;
245+ this . ensureSafeReturnToParamForAuthorize ( req )
246+ . then ( ( ) => {
247+ this . authenticator
248+ . authorize ( req , res , next )
249+ . catch ( ( err ) => log . error ( "authenticator.authorize" , err ) ) ;
250+ } )
251+ . catch ( ( err ) => {
252+ log . error ( "authenticator.authorize" , err ) ;
253+ } ) ;
245254 } ) ;
246255 router . get ( "/deauthorize" , ( req : express . Request , res : express . Response , next : express . NextFunction ) => {
247256 if ( ! User . is ( req . user ) ) {
@@ -252,8 +261,16 @@ export class UserController {
252261 res . sendStatus ( 403 ) ;
253262 return ;
254263 }
255- this . ensureSafeReturnToParamForAuthorize ( req ) ;
256- this . authenticator . deauthorize ( req , res , next ) . catch ( ( err ) => log . error ( "authenticator.deauthorize" , err ) ) ;
264+ this . ensureSafeReturnToParam ( req ) ;
265+ this . ensureSafeReturnToParamForAuthorize ( req )
266+ . then ( ( ) => {
267+ this . authenticator
268+ . deauthorize ( req , res , next )
269+ . catch ( ( err ) => log . error ( "authenticator.deauthorize" , err ) ) ;
270+ } )
271+ . catch ( ( err ) => {
272+ log . error ( "authenticator.deauthorize" , err ) ;
273+ } ) ;
257274 } ) ;
258275 router . get ( "/logout" , async ( req : express . Request , res : express . Response , next : express . NextFunction ) => {
259276 const logContext = LogContext . from ( { user : req . user , request : req } ) ;
@@ -614,8 +631,20 @@ export class UserController {
614631 return returnTo ;
615632 }
616633
617- protected ensureSafeReturnToParamForAuthorize ( req : express . Request ) : string | undefined {
618- const returnTo = getSafeReturnToParam ( req , ( url ) => validateAuthorizeReturnToUrl ( url , this . config . hostUrl ) ) ;
634+ // TODO(gpl): Once we drop the feature flag, turn into the same form as above method.
635+ protected async ensureSafeReturnToParamForAuthorize ( req : express . Request ) : Promise < string | undefined > {
636+ let returnTo = getSafeReturnToParam ( req ) ;
637+ if ( returnTo ) {
638+ const isStrictAuthorizeValidationEnabled = await getFeatureFlagEnableStrictAuthorizeReturnTo ( ) ;
639+ if ( isStrictAuthorizeValidationEnabled ) {
640+ // Validate returnTo URL against allowlist for authorize API
641+ if ( ! validateAuthorizeReturnToUrl ( returnTo , this . config . hostUrl ) ) {
642+ log . warn ( `Invalid returnTo URL rejected for authorize: ${ returnTo } ` , { "login-flow" : true } ) ;
643+ returnTo = undefined ;
644+ }
645+ }
646+ }
647+
619648 req . query . returnTo = returnTo ;
620649 return returnTo ;
621650 }
0 commit comments