2014-09-04 26 views
0

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

而且按类型的我的理解实体的属性很容易出现的JavaScript/HTML注入

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

其中一个我看到的选项是用于验证可使用流利的验证或任何其他验证库

+0

是的,你应该用流利的验证或其他验证机制来净化被作为一个传递的所有值请求到您的ServiceStack服务。 ServiceStack不会为你做这件事,毕竟在服务请求中发送HTML和/或JavaScript可能是完全合法的(即你的服务是博客的内容管理器),并且假设请求是错误的一次注射攻击。 ServiceStack不会被限制为仅由Web应用程序使用,因此服务决定哪些值适合。尽管ServiceStack从SQL注入中完成。 – Scott 2014-09-04 12:37:59

+0

这很有道理,谢谢@Scott。让我检查是否有任何其他方法验证相同的 – Shiljo 2014-09-04 12:57:15

+0

Hi @ Shhil,你试过'[HtmlEncode]'属性方法吗? :) – Scott 2014-09-05 06:56:26

回答

2

使用验证:

是的,你应该用流利的验证或其他验证机制清理作为请求传递给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任何串任何HTML通过对正则表达式检查更一般的检查任何DTO的一个例外,但我会尽量少用。

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 
{ 
    ... 
} 
+0

代码如期工作谢谢@scott – Shiljo 2014-09-05 13:27:08

+0

我添加了addtinal属性[IgnoreHtmlContent]来忽略整个实体本身。目前我还使用[EncodeHtml]属性。不知道这是否是处理问题的正确方法 – Shiljo 2014-09-05 14:06:47

+0

@Shil我已更新以包含更多通用代码,这些代码将防止将任何HTML包含在DTO中。 – Scott 2014-09-05 15:32:59