2010-08-13 96 views
9

谷歌變成了各種各樣的消毒Web訪問查詢的討論,但我沒有找到任何解決什麼,我關心的是:在C#程序消毒SQL數據

消毒用戶輸入數據。這必須通過可逆轉化來完成,而不是通過去除。作爲問題的一個簡單例子,我不想破壞愛爾蘭人的名字。

什麼是最好的方法,是否有任何庫函數呢?

+7

是否將可能包含撇號的數據傳遞給SQL查詢?如果您使用SQL Parameter對象,那應該不成問題。你會得到你的消毒,並且你的數據中的任何重要字符都應該被正確地轉義。 – 2010-08-13 17:53:02

+0

同意的參數化查詢是可行的方法。 – driis 2010-08-13 17:57:53

+0

我只通過業務邏輯生成SQL查詢。 – Jeroen 2010-08-13 18:11:45

回答

9

這取決於您使用的SQL數據庫。例如,如果你想在MySQL中使用單引號,你需要使用一個反斜槓Dangerous:'和一個逃脫的轉義字符:\'。對於MS-SQL,情況完全不同,危險:'轉義:''。當您以這種方式轉義數據時,不會刪除任何內容,它是一種表示控制字符的方式,如字面形式的引號。

下面是使用MS-SQL和C#參數化查詢,從Docs採取的一個例子:

private static void UpdateDemographics(Int32 customerID, 
    string demoXml, string connectionString) 
{ 
    // Update the demographics for a store, which is stored 
    // in an xml column. 
    string commandText = "UPDATE Sales.Store SET Demographics = @demographics " 
     + "WHERE CustomerID = @ID;"; 

    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     SqlCommand command = new SqlCommand(commandText, connection); 
     command.Parameters.Add("@ID", SqlDbType.Int); 
     command.Parameters["@ID"].Value = customerID; 

     // Use AddWithValue to assign Demographics. 
     // SQL Server will implicitly convert strings into XML. 
     command.Parameters.AddWithValue("@demographics", demoXml); 

     try 
     { 
      connection.Open(); 
      Int32 rowsAffected = command.ExecuteNonQuery(); 
      Console.WriteLine("RowsAffected: {0}", rowsAffected); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 
} 

對於MySQL我不知道,你可以使用參數化查詢庫。您應該使用mysql_real_escape_string()或者任意使用此功能。:

public static string MySqlEscape(this string usString) 
{ 
    if (usString == null) 
    { 
     return null; 
    } 
    // SQL Encoding for MySQL Recommended here: 
    // http://au.php.net/manual/en/function.mysql-real-escape-string.php 
    // it escapes \r, \n, \x00, \x1a, baskslash, single quotes, and double quotes 
    return Regex.Replace(usString, @"[\r\n\x00\x1a\\'""]", @"\$0"); 
} 
+1

我意識到這是一個較舊的帖子,但PHP [5.0 +]確實通過MySQLi(http://php.net/manual/en/book.mysqli.php)和PDO庫(http:///php.net/manual/en/book.pdo.php)。 – 2012-06-19 09:52:06

+0

@Tieson T.和adodb,以及參數化查詢是最好的選擇。 – rook 2012-06-19 17:42:13

+1

fyi,mysql_real_escape_string已被棄用 – 2013-04-22 18:29:36

0

使用適當構造的DAL與SQL參數對象交給存儲過程,您不必擔心這一點。實現業務對象和dal以足夠抽象用戶輸入,以使其不作爲SQL執行,而是作爲值進行識別。示例很有趣:

public class SomeDal 
{ 
    public void CreateUser(User userToBeCreated) 
    { 
     using(connection bla bla) 
     { 
      // create and execute a command object filling its parameters with data from the User object 
     } 
    } 
} 

public class User 
{ 
    public string Name { get; set; } 
    ... 
} 

public class UserBL 
{ 
    public CreateUser(User userToBeCreated) 
    { 
     SomeDal myDal = new SomeDal(); 
     myDal.CreateUser(userToBeCreated); 
    } 
} 

public class SomeUI 
{ 
    public void HandleCreateClick(object sender, e ButtonClickEventArgs) 
    { 
     User userToBeCreated = new User() { Name = txtName.Text }; 
     UserBL userBl = new UserBL(); 
     userBl.CreateUser(userToBeCreated); 
    } 
} 
+0

我看到parematerized命令是要走的路,但您的示例代碼與它們無關! – 2010-08-13 20:26:33

+0

@Loren Pechtel:評論說要使用它們,而且你希望你的用戶輸入填充一個像User的業務對象,它充當傳輸到dal的業務對象,它創建命令和參數。這種抽象將數據庫中的用戶與安全性分離,因爲你可以創建一個UserValidator和其他類似的東西,使得他們的輸入不僅可以從SQL注入中安全使用,而且可以避免無效值。 – 2010-08-13 20:31:34

+0

我同意你需要一個檢查有效性的層次,但這與保持系統免於奧尼爾先生的窒息是分開的。 – 2010-08-14 04:51:36