@@ -21,6 +21,7 @@ package com.tesobe.oidc.endpoints
2121
2222import cats .effect .IO
2323import com .tesobe .oidc .auth .{AuthService , CodeService }
24+ import com .tesobe .oidc .endpoints .HtmlUtils .htmlEncode
2425import com .tesobe .oidc .models .{OidcError , User }
2526import com .tesobe .oidc .ratelimit .RateLimitService
2627import com .tesobe .oidc .config .OidcConfig
@@ -40,10 +41,6 @@ class AuthEndpoint(
4041
4142 private val logger = LoggerFactory .getLogger(getClass)
4243
43- private def htmlEncode (s : String ): String =
44- s.replace(" &" , " &" ).replace(" <" , " <" )
45- .replace(" >" , " >" ).replace(" \" " , " "" ).replace(" '" , " '" )
46-
4744 // Test logging immediately when class is created
4845 logger.info(" AuthEndpoint created - logging is working!" )
4946 println(" AuthEndpoint created - logging is working!" )
@@ -328,7 +325,7 @@ class AuthEndpoint(
328325 s " Error handling login submission: ${error.getMessage}" ,
329326 error
330327 )
331- BadRequest (s " Invalid form data: ${error.getMessage} " )
328+ BadRequest (" Invalid form data. Please try again. " )
332329 }
333330
334331 private def generateCodeForUser (
@@ -363,15 +360,15 @@ class AuthEndpoint(
363360 clientOpt <- authService.findClientByClientIdThatIsKey(clientId)
364361
365362 stateParam = state
366- .map(s => s """ <input type="hidden" name="state" value=" $s "> """ )
363+ .map(s => s """ <input type="hidden" name="state" value=" ${htmlEncode(s)} "> """ )
367364 .getOrElse(" " )
368365 nonceParam = nonce
369- .map(n => s """ <input type="hidden" name="nonce" value=" $n "> """ )
366+ .map(n => s """ <input type="hidden" name="nonce" value=" ${htmlEncode(n)} "> """ )
370367 .getOrElse(" " )
371368
372369 providerOptions = providers
373370 .map { provider =>
374- s """ <option value=" $provider"> $provider</option> """
371+ s """ <option value=" ${htmlEncode( provider)} "> ${htmlEncode( provider)} </option> """
375372 }
376373 .mkString(" \n " )
377374
@@ -473,7 +470,7 @@ class AuthEndpoint(
473470 </div> """
474471 } else if (providers.length == 1 ) {
475472 // Single provider in production: use hidden field
476- s """ <input type="hidden" name="provider" value=" ${providers.head}"> """
473+ s """ <input type="hidden" name="provider" value=" ${htmlEncode( providers.head) }"> """
477474 } else {
478475 // No providers - shouldn't happen but handle gracefully
479476 s """ <div class="form-group">
@@ -484,9 +481,9 @@ class AuthEndpoint(
484481 </div> """
485482 }}
486483
487- <input type="hidden" name="client_id" value=" $clientId">
488- <input type="hidden" name="redirect_uri" value=" $redirectUri">
489- <input type="hidden" name="scope" value=" $scope">
484+ <input type="hidden" name="client_id" value=" ${htmlEncode( clientId)} ">
485+ <input type="hidden" name="redirect_uri" value=" ${htmlEncode( redirectUri)} ">
486+ <input type="hidden" name="scope" value=" ${htmlEncode( scope)} ">
490487 $stateParam
491488 $nonceParam
492489
0 commit comments