-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Sanitization middleware): add sanetization middleware (#20)
* add sanetization middleware * complete sanetizing middleware
- Loading branch information
1 parent
51fc234
commit eefa3c9
Showing
3 changed files
with
85 additions
and
1 deletion.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
RelationshipAnalysis/Middlewares/SanitizationMiddleware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
using System.Text; | ||
using Ganss.Xss; | ||
using Microsoft.AspNetCore.Mvc.Controllers; | ||
using Newtonsoft.Json; | ||
|
||
namespace RelationshipAnalysis.Middlewares; | ||
public class SanitizationMiddleware | ||
{ | ||
private readonly RequestDelegate _next; | ||
private readonly HtmlSanitizer _sanitizer; | ||
|
||
public SanitizationMiddleware(RequestDelegate next) | ||
{ | ||
_next = next; | ||
_sanitizer = new HtmlSanitizer(); | ||
} | ||
|
||
public async Task InvokeAsync(HttpContext context) | ||
{ | ||
if (context.Request.ContentType != null && context.Request.ContentType.Contains("application/json")) | ||
{ | ||
context.Request.EnableBuffering(); | ||
var body = await new StreamReader(context.Request.Body).ReadToEndAsync(); | ||
context.Request.Body.Position = 0; | ||
|
||
var type = GetRequestDtoType(context); | ||
if (type != null) | ||
{ | ||
object sanitizedDto; | ||
if (type == typeof(List<string>)) | ||
{ | ||
var dto = JsonConvert.DeserializeObject<IEnumerable<string>>(body); | ||
sanitizedDto = SanitizeEnumerable(dto); | ||
} | ||
else | ||
{ | ||
var dto = JsonConvert.DeserializeObject(body, type); | ||
sanitizedDto = SanitizeDto(dto); | ||
} | ||
|
||
var sanitizedBody = JsonConvert.SerializeObject(sanitizedDto); | ||
var buffer = Encoding.UTF8.GetBytes(sanitizedBody); | ||
context.Request.Body = new MemoryStream(buffer); | ||
} | ||
} | ||
|
||
await _next(context); | ||
} | ||
|
||
private Type GetRequestDtoType(HttpContext context) | ||
{ | ||
var endpoint = context.GetEndpoint(); | ||
var actionDescriptor = endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>(); | ||
if (actionDescriptor != null) | ||
{ | ||
var parameters = actionDescriptor.Parameters; | ||
var dtoParameter = parameters.FirstOrDefault(p => p.ParameterType.IsClass && p.ParameterType != typeof(string)); | ||
return dtoParameter?.ParameterType; | ||
} | ||
return null; | ||
} | ||
|
||
private IEnumerable<string> SanitizeEnumerable(IEnumerable<string> dto) | ||
{ | ||
return dto.Select(str => _sanitizer.Sanitize(str)); | ||
} | ||
private object SanitizeDto(object dto) | ||
{ | ||
var properties = dto.GetType().GetProperties().Where(p => p.PropertyType == typeof(string) && p.CanWrite && p.CanRead); | ||
|
||
foreach (var property in properties) | ||
{ | ||
var value = (string)property.GetValue(dto); | ||
if (value != null) | ||
{ | ||
property.SetValue(dto, _sanitizer.Sanitize(value)); | ||
} | ||
} | ||
|
||
return dto; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters