Avoid potential server side request forgeries (SSRFs)
This product is not supported for your selected
Datadog site. (
).
ID: csharp-security/avoid-potential-ssrf
Language: C#
Severity: Error
Category: Security
CWE: 918
Description
No description found
Non-Compliant Code Examples
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
public class DocumentController : Controller
{
private readonly HttpClient _httpClient;
public DocumentController(HttpClient httpClient)
{
_httpClient = httpClient;
}
[HttpPost]
public async Task<IActionResult> FetchDocument(string documentUrl)
{
var response = await _httpClient.GetAsync(documentUrl); // Noncompliant
var content = await response.Content.ReadAsStringAsync();
return Content(content);
}
}
Compliant Code Examples
public class DocumentController : Controller
{
private readonly HttpClient _httpClient;
private readonly HashSet<string> _allowedHosts = new()
{
"api.company.com",
"documents.trusted.org"
};
public DocumentController(HttpClient httpClient)
{
_httpClient = httpClient;
}
[HttpPost]
public async Task<IActionResult> FetchDocument(string documentUrl)
{
if (!Uri.TryCreate(documentUrl, UriKind.Absolute, out Uri uri))
{
return BadRequest("Invalid URL format");
}
if (uri.Scheme != "https" || !_allowedHosts.Contains(uri.Host))
{
return BadRequest("URL not allowed");
}
var response = await _httpClient.GetAsync(documentUrl);
var content = await response.Content.ReadAsStringAsync();
return Content(content);
}
public async Task<MyResult> HandleAsync(CancellationToken cancellationToken) {
var countries = await repository.GetAsync(cancellationToken);
}
}
public class RedisRepository
{
private readonly object _redis;
private readonly ILogger _logger;
public async Task<bool> DeleteKey(string key)
{
var cache = ((dynamic)_redis).GetDatabase();
return await cache.KeyDeleteAsync(key);
}
public async Task<string?> GetString(string key)
{
var cache = ((dynamic)_redis).GetDatabase();
return (string?)await cache.StringGetAsync(key);
}
}
using System.Net.Http.Headers;
public class AuthTokenHandler(string scope) : DelegatingHandler
{
private readonly TokenCredential _credential = new DefaultAzureCredential();
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken
)
{
var tokenRequestContext = new TokenRequestContext([scope]);
var accessToken = await _credential.GetTokenAsync(tokenRequestContext, cancellationToken);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Token);
return await base.SendAsync(request, cancellationToken);
}
}
Seamless integrations. Try Datadog Code Security