@@ -16,8 +16,13 @@ namespace EasyAuthForK8s.Web.Models;
1616
1717internal static class ModelExtensions
1818{
19+ //from rfc7230 US-ASCII visual characters not allowed in a token (DQUOTE and "(),/:;<=>?@[\]{}")
20+ private static int [ ] invalid_token_chars = new int [ ] { 34 , 40 , 41 , 44 , 47 , 58 , 59 , 60 , 61 , 62 , 63 , 64 , 91 , 92 , 93 , 123 , 125 } ;
21+ const string EMPTY_HEADER_NAME = "illegal-name" ;
22+
1923 public static EasyAuthState EasyAuthStateFromHttpContext ( this HttpContext context )
2024 {
25+
2126 //see if state exists in property bag, and return it
2227 if ( context . Items . ContainsKey ( Constants . StateCookieName ) )
2328 {
@@ -176,7 +181,7 @@ internal static void AppendResponseHeaders(this UserInfoPayload payload, IHeader
176181
177182 void addHeader ( string name , string value )
178183 {
179- string headerName = SanitizeHeaderName ( $ "{ configOptions . ResponseHeaderPrefix } { name } ") ;
184+ string headerName = SanitizeHeaderName ( $ "{ configOptions . ResponseHeaderPrefix } { ClaimNameFromUri ( name ) } ") ;
180185 string encodedValue = EncodeValue ( value , configOptions . ClaimEncodingMethod ) ;
181186
182187 //nginx will only forward the first header of a given name,
@@ -240,16 +245,42 @@ private static string EncodeValue(string value, EasyAuthConfigurationOptions.Enc
240245 _ => value ,
241246 } ;
242247 }
243- private static string SanitizeHeaderName ( string name )
248+ //strips out any illegal characters
249+ internal static string SanitizeHeaderName ( string name )
244250 {
245251 if ( string . IsNullOrEmpty ( name ) )
246252 {
247253 throw new ArgumentNullException ( "name" ) ;
248254 }
249255
250- string clean = new string ( name . Where ( c => c >= 32 && c < 127 ) . ToArray ( ) ) ;
256+ string clean = new string ( name . Where ( c => c >= 32 && c < 127 && ! invalid_token_chars . Contains ( c ) ) . ToArray ( ) ) ;
251257
252- return clean . Replace ( '_' , '-' ) . ToLower ( ) ;
258+ //edge case: the original name contains ZERO valid characters
259+ //just return a default. there's no reason to throw when the app may ignore this header anyway
260+ if ( clean . Length == 0 )
261+ return EMPTY_HEADER_NAME ;
262+ else
263+ return clean . Replace ( '_' , '-' ) . ToLower ( ) ;
264+ }
265+ //while this is not entirely necessary, and might lead to name-uniqueness conflicts
266+ //it seems like a reasonable compromize to create a more "friendly" header name
267+ internal static string ClaimNameFromUri ( string name )
268+ {
269+ if ( string . IsNullOrEmpty ( name ) )
270+ {
271+ throw new ArgumentNullException ( "name" ) ;
272+ }
273+ if ( name . Contains ( "/" ) )
274+ {
275+ var split = name . Split ( '/' , StringSplitOptions . RemoveEmptyEntries ) ;
276+ if ( split . Length > 1 )
277+ return split [ split . Length - 1 ] ;
278+ else
279+ //edge case: the original name contains nothing but forward slashes
280+ return EMPTY_HEADER_NAME ;
281+ }
282+ else
283+ return name ;
253284 }
254285}
255286
0 commit comments