2010-07-31 29 views
7

.NET或其中一種語言強制執行清除不可信數據......或防止意外變量用於錯誤地點?擴展類型安全性以防止對需要「乾淨」數據的函數使用髒數據

這種情況的一個示例是,在SQL事務中使用用戶POST數據和「原始」響應。這可能會導致客戶端腳本漏洞的任何內容泄露給整個服務器受到威脅。

另一個例子是我必須將數據傳遞給COM對象進行進一步處理。

作爲C#,ASP.net和SQL開發人員,我的選擇是什麼?以確保我的用戶的髒位在清理前不會觸及任何內部的東西?是否有我可以利用的運行時(或編譯器)功能?

缺乏語言實際執行它,也許我可以只爲_dirty後綴添加到我的傳入變量。這是你推薦的最佳做法嗎?

專業人員如何解決這個問題?

更新

這裏是我要去

概念方向這基於

例如給出到目前爲止(具體SteveCzetty和Erlend)的答案是有點啓發:

public Interface ICleanForJavascript { bool IsCleanForJavascript(); }  

public Interface ICleanForXSS { bool IsCleanForJavascript(); } 

public class DirtyData 
{ 
    string Name {get; set;} 
} 

public class CleanData 
{ 
    private CleanData() {} 
    string Name {get; private set;} 


    // Perhaps use casting to support the conversion from Dirty to Clean data 
    // Might use this in an option explicit DirtyData CleanData(object o); command 
    public static CleanData Validate(DirtyData d) 
    { 
     CleanData data = new CleanData(); 
     if (ValidateString(d.Name)) 
     { 
      data.Name = d.Name 
     } 
     else 
     { 
      throw new ValidationException(); 
     } 
     return CleanData; 
    } 
} 

[RequiresCleanedDataAttribute(ICleanForJavascript)] 
public void DoSomething(CleanData data) 
{ 
    //... 
} 

Attribute RequiresCleanedDataAttribute(object arrayOfCleanings[]) 
{ 
    // do some reflection on the method signature and see if the object supports the required interfaces 
} 

隨着上述,然後:

DoSomething(new DirtyData()); // Compiler Error, or runtime error if Attribute validation fails 
DoSomething(CleanData.Validate(new DirtyData())); // Compiles 
+0

我想看到的,當髒數據被髮送到錯誤的地方,將拋出一個編譯器錯誤的任何技術。 – LamonteCristo 2012-02-16 15:07:29

+0

過於寬泛的問題 – 2012-02-23 09:01:47

回答

7

可.NET或它的一個許多語言執行不可信數據

是的,它可以,但不是在路上你問的清洗。相反,你通過正確的參數化來確保乾淨的sql。例如:

string sql = "SELECT * FROM [table] WHERE [column] = @value"; 
using (var cn = new SqlConnection("connection string here")) 
using (var cmd = new SqlCommand(sql, cn) 
{ 
    cmd.Parameters.Add("@value").Value = "'';DROP Table Users;--"; 
    cn.Open(); 
    SomeControl.DataSource = cmd.ExecuteReader(); 
    SomeControl.DataBind(); 
} 

即使存在明顯的注入嘗試,該代碼仍可以非常安全地運行。原因是SqlCommand對象的參數集合是從來沒有直接在查詢中被替換。數據被髮送到服務器並完全獨立於代碼處理,因此無論用戶輸入什麼內容,所有內容都是安全的。

你所做的任何嘗試「清理」請求的嘗試總是與餅乾進行軍備競賽。這樣,正確的方式就是將數據和代碼分開。

+0

感謝您使用存儲過程的提示。這將在一定程度上解決SQL問題,但不會阻止或告訴我的隊友我發送的是乾淨或髒的數據。我正在考慮更多類型的[屬性]。這個元數據將被用來在一個全新的層面上強制類型一致性。 – LamonteCristo 2010-07-31 03:18:48

+1

@Maker - 這與存儲過程無關。請注意,我的文章中的sql字符串是ad hoc sql。這不是一個存儲過程。參數化查詢是不同的動物。 – 2010-07-31 04:13:18

+0

我正在使用Linq與實體框架。這可能不適用於我將XSS數據保存到數據庫然後將其發回的情況。 – LamonteCristo 2012-02-22 21:57:42

4

你似乎認爲只能有一種方法來sanitize()數據。問題在於,漏洞高度依賴於數據的使用方式,實際上這種方法非常困難。例如sql注入和xss有很少的共同點,他們不應該使用相同的功能。其實很少有之間的任何injection flaws之間的相似之處。

也就是說,Taint checking的最佳實施方案是ruby's safe mode。 IronRuby讓你可以在.net上使用ruby。這通過有一個衛生功能列表,將變量標記爲乾淨。但即使這樣也不會阻止一切,如果你看看owasp top 10,只有A1-Injection和A2-XSS漏洞是由於受污染的輸入引起的,其餘的則不是,最明顯的是CSRF。

+0

這正是我的標題,儘管我沒有專注於清潔我的數據的單一方法。在我期望的解決方案的示例實現中,我將擁有一個基類的Object,其中包含一個基於標誌的Enum,用於指示變量是否已清理以及使用何種類型的清理。當然,這種方法是僅限運行時的方法。我會花點時間研究你提到的鏈接。 – LamonteCristo 2010-08-03 19:03:36

+2

問題是輸入本身不能是惡意的。攻擊者可能有惡意的意圖發送,但問題只會在特定的上下文中出現(如Rook提到的)。所以,如果你想在使用之前對其進行劃分,你會對它做什麼清理? SQL注入? HTML中的XSS? JavaScript中的XSS? XSS在CSS中?真的沒有好的答案。如果將數據同時用於sql注入和HTML,會發生什麼?它可能會被破壞,因爲一個環境中的有效字符在另一個環境中是非法的,因此它的顯示會在法律環境中被破壞。 – Erlend 2012-02-22 13:40:02

+0

數據必須針對上下文進行消毒。當數據進入應用程序時,應該對應用程序的域進行消毒。包含

1

使用Code Contracts...(also in pdf format)

基本上,您要求CLR控制流圖上的附加約束,該約束防止任何函數使用尚未清理的數據。

像其他人一樣,消毒用戶輸入是微不足道的;它確保只有有效的數據是程序員監督引入安全漏洞時。代碼合同將有效地擴展編譯器,以限制只使用清理數據的方法(但是您可以定義該方法),同時保證不能將字符串添加到Int。

參見: Static Program Analysis