2014-09-04 60 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