防止"请求实体"上的JavaScript / HTML注入在ServiceStack中

时间:2014-09-04 12:20:03

标签: servicestack ormlite-servicestack

我不确定 ServiceStack 是否有机制阻止实体(请求实体)属性上的“JavaScript / HTML注入”。

另据我所知,实体的字符串类型的属性容易出现JavaScript / HTML注入

如果没有内置机制,请建议我一个更好的选择。

我看到用于验证的选项之一可能是使用 Fluent验证或任何其他验证库

1 个答案:

答案 0 :(得分:2)

使用验证:

是的,您应该使用Fluent验证或其他验证机制来清理作为请求传递给ServiceStack服务的所有值。

为什么ServiceStack不应该为您清理:

ServiceStack不会为您执行此操作,毕竟在对服务的请求中发送HTML和/或JavaScript可能是完全合法的(即,您的服务是博客的内容管理员),并且假设是错误的请求是注入攻击。

ServiceStack不仅限于被Web应用程序使用,因此由服务决定哪些值是合适的。

应该注意的是,ServiceStack通过转义所有参数来防止SQL注入。

编码HTML实体:

如果您担心HTML注入,那么您应该考虑编码HTML实体,然后返回的任何不安全值都不会影响您的结果。您可以使用此请求过滤器轻松完成此操作,并使用属性[EncodeHtml]标记DTO。

GlobalRequestFilters.Add((req,res,dto) => {
    var dtoType = dto.GetType();
    var filteredProperties = dtoType.GetPublicProperties().Where(p => p.PropertyType == typeof(string) && p.HasAttribute<EncodeHtmlAttribute>() && p.CanWrite);
    foreach(var property in filteredProperties)
        property.SetValue(dto, HttpUtility.HtmlEncode(property.GetValue(dto, null)), null);
});

在DTO上,将[EncodeHtml]属性添加到要保护的属性中。

[Route("/test", "GET")]
public class Test
{
    public string UnsafeMessage { get; set; }

    [EncodeHtml]
    public string SafeMessage { get; set; }
}

属性声明只是:

public class EncodeHtmlAttribute : Attribute {}

然后当您发送请求时:

/test?unsafeMessage=<b>I am evil</b>&safeMessage=<b>I am good</b>

结果将是

UnsafeMessage: "<b>I am evil</b>"
SafeMessage: "&lt;b&gt;I am good&lt;/b&gt;"

我希望这会有所帮助。


根据您的建议,如果您想在可能包含HTML的任何DTO上抛出异常,那么您可以使用更通用的检查,通过检查正则表达式来阻止DTO上任何字符串中的任何HTML,但我会这样做很少。

GlobalRequestFilters.Add((req,res,dto) => {
    var dtoType = dto.GetType();
    if(!dtoType.HasAttribute<PreventHtmlAttribute>())
        return;
    var filteredProperties = dtoType.GetPublicProperties().Where(p => p.PropertyType == typeof(string));
    foreach(var property in filteredProperties){
        var value = property.GetValue(dto, null) as string;
        if(value != null && Regex.Match(value, @"<[^>]*>", RegexOptions.IgnoreCase).Success)
            throw new HttpError(System.Net.HttpStatusCode.BadRequest, "400", "HTML is not permitted in the request");
    }
});

然后使用此属性:

public class PreventHtmlAttribute : Attribute {}

在DTO上:

[PreventHtml]
[Route("/test", "GET")]
public class Test
{
    ...
}