@@ -1154,17 +1154,64 @@ private List<ValidationError> ValidateJsonAgainstSchema(string jsonData, JSchema
11541154 return null ;
11551155 }
11561156
1157- // Basic sanity checks to ensure the authentication configuration is usable .
1157+ // Perform stricter validation on the authentication configuration.
11581158 // If it fails validation, treat it as if no authentication was provided.
1159- if ( string . IsNullOrWhiteSpace ( auth . ApiKey )
1160- && string . IsNullOrWhiteSpace ( auth . BearerToken )
1161- && auth . BasicAuth == null
1162- && ( auth . CustomHeaders == null || auth . CustomHeaders . Count == 0 ) )
1159+ var hasApiKey = ! string . IsNullOrWhiteSpace ( auth . ApiKey ) ;
1160+ var hasBearer = ! string . IsNullOrWhiteSpace ( auth . BearerToken ) ;
1161+ var hasBasic = auth . BasicAuth != null
1162+ && ! string . IsNullOrWhiteSpace ( auth . BasicAuth . Username )
1163+ && ! string . IsNullOrWhiteSpace ( auth . BasicAuth . Password ) ;
1164+ var hasCustomHeaders = auth . CustomHeaders != null && auth . CustomHeaders . Count > 0 ;
1165+
1166+ var mechanismsCount = 0 ;
1167+ if ( hasApiKey ) mechanismsCount ++ ;
1168+ if ( hasBearer ) mechanismsCount ++ ;
1169+ if ( hasBasic ) mechanismsCount ++ ;
1170+ if ( hasCustomHeaders ) mechanismsCount ++ ;
1171+
1172+ // Require at least one and at most one primary authentication mechanism.
1173+ if ( mechanismsCount != 1 )
11631174 {
11641175 return null ;
11651176 }
11661177
1167- return auth ;
1178+ // Return a sanitised copy so that downstream code does not operate on the original user object.
1179+ var validated = new DataSourceAuthentication ( ) ;
1180+
1181+ if ( hasApiKey )
1182+ {
1183+ validated . ApiKey = auth . ApiKey ! . Trim ( ) ;
1184+ }
1185+ else if ( hasBearer )
1186+ {
1187+ validated . BearerToken = auth . BearerToken ! . Trim ( ) ;
1188+ }
1189+ else if ( hasBasic )
1190+ {
1191+ validated . BasicAuth = new BasicAuthentication
1192+ {
1193+ Username = auth . BasicAuth ! . Username . Trim ( ) ,
1194+ Password = auth . BasicAuth . Password
1195+ } ;
1196+ }
1197+ else if ( hasCustomHeaders )
1198+ {
1199+ // Copy only non-empty header names and values.
1200+ validated . CustomHeaders = new Dictionary < string , string > ( ) ;
1201+ foreach ( var kvp in auth . CustomHeaders ! )
1202+ {
1203+ if ( ! string . IsNullOrWhiteSpace ( kvp . Key ) && ! string . IsNullOrWhiteSpace ( kvp . Value ) )
1204+ {
1205+ validated . CustomHeaders [ kvp . Key . Trim ( ) ] = kvp . Value ;
1206+ }
1207+ }
1208+ if ( validated . CustomHeaders . Count == 0 )
1209+ {
1210+ return null ;
1211+ }
1212+ }
1213+
1214+ return validated ;
11681215 }
11691216
11701217 private async Task < JObject > FetchOpenApiSpecFromUrlAsync ( string specUrl , DataSourceAuthentication ? auth , CancellationToken cancellationToken , bool resolveReferences = true )
@@ -1181,7 +1228,7 @@ private async Task<JObject> FetchOpenApiSpecFromUrlAsync(string specUrl, DataSou
11811228
11821229 using var request = new HttpRequestMessage ( HttpMethod . Get , specUrl ) ;
11831230
1184- // Apply authentication only if it passes basic validation
1231+ // Apply authentication only if it passes strict validation
11851232 var validatedAuth = ValidateAuthentication ( auth ) ;
11861233 if ( validatedAuth != null )
11871234 {
@@ -1198,7 +1245,7 @@ private async Task<JObject> FetchOpenApiSpecFromUrlAsync(string specUrl, DataSou
11981245 // or when endpoints won't be tested
11991246 if ( resolveReferences )
12001247 {
1201- var resolvedContent = await _schemaResolverService . ResolveAsync ( content , specUrl , auth ) ;
1248+ var resolvedContent = await _schemaResolverService . ResolveAsync ( content , specUrl , validatedAuth ) ;
12021249 return JObject . Parse ( resolvedContent ) ;
12031250 }
12041251
0 commit comments