Sonar = Enterprise Edition v2025.1 (102418)
I received the error that a url that was passed in as a parameter makes the Server-side request vulnerable to forging attacks.
Change this code to not construct the URL from user-controlled data.
Server-side requests should not be vulnerable to forging attacks roslyn.sonaranalyzer.security.cs:S5144
1 SOURCE a user can craft an HTTP request with malicious content
public async Task<dynamic> ProxySearch([FromBody] ProxyParameters proxyParameters)
2 This invocation can propagate malicious content to its return value
Uri uri = new Uri(proxyParameters.url);
3 This invocation can propagate malicious content to its return value
4 SINK this invocation is not safe; a malicious value can be used as argument
Navigate locations
var response = await client.GetAsync(proxyParameters.url);
Here is my updated code that still gets the error.
[Route("api/[controller]")]
[ApiController]
public class ProxyController : ControllerBase
{
private readonly string[] allowedSchemes = { "https" };
private readonly string[] allowedDomains = { "trusted1.example.com", "trusted2.example.com" };
[HttpPost()]
public async Task<dynamic> ProxySearch([FromBody] ProxyParameters proxyParameters)
{
try
{
var clientHandler = new HttpClientHandler();
Uri uri = new Uri(proxyParameters.url);
if (!allowedDomains.Contains(uri.Host) && !allowedSchemes.Contains(uri.Scheme))
{
return BadRequest();
}
using (var client = new HttpClient(clientHandler))
{
var response = await client.GetAsync(proxyParameters.url);
response.EnsureSuccessStatusCode();
return new
{
statusCode = response.StatusCode,
content = await response.Content.ReadAsStringAsync()
};
}
}
catch (Exception e)
{
return new
{
error = e.Message,
stack = e.StackTrace,
innerError = e.InnerException?.Message ?? string.Empty
};
}
}
}
I changed the code to do exactly what the fix example said, which is below.
public class ExampleController: Controller
{
private readonly string[] allowedSchemes = { "https" };
private readonly string[] allowedDomains = { "trusted1.example.com", "trusted2.example.com" };
[HttpGet]
public async Task<IActionResult> ImageFetch(string location)
{
Uri uri = new Uri(location);
if (!allowedDomains.Contains(uri.Host) && !allowedSchemes.Contains(uri.Scheme))
{
return BadRequest();
}
await using Stream stream =
await client.GetStreamAsync(location);
var exampleImage =
await JsonSerializer.DeserializeAsync<ExampleImage>(stream);
return Ok(example ?? new());
}
}
It is citing the same issue even though I remedied the issue as instructed. What are other options for this. The URL will be incoming and I can validate the scheme and the domain, but not the rest of the URL as they will be dynamic.