2010-08-13 8 views
9

Google zamienia się wszelkiego rodzaju dyskusje na temat odkażania zapytania o dostęp do sieci, ale nie jestem znalezienie czegokolwiek adresowania co Martwię się:dane Dezynfekcja SQL

odkażania danych wejściowych użytkownika w programie C#. Trzeba to zrobić poprzez przemianę odwracalną, a nie przez usunięcie. Jako prosty przykład problemu nie chcę manipulować irlandzkimi nazwami.

Jakie jest najlepsze podejście i czy istnieje jakaś funkcja biblioteczna, która to robi?

+7

masz na myśli przekazywania danych, które mogą zawierać apostrofy do kwerendy SQL? Jeśli używasz obiektów SQL Parameter, nie powinno to stanowić problemu. Dostaniesz swoją dezynfekcję, a wszelkie znaczące postacie w twoich danych powinny zostać odpowiednio usunięte. –

+0

Uzgodnione, sparametryzowane zapytania to droga. – driis

+0

Generuję zapytania SQL tylko za pomocą logiki biznesowej. – Jeroen

Odpowiedz

9

To zależy od bazy danych SQL, z której korzystasz. Na przykład, jeśli chcesz użyć pojedynczego cudzysłowu w MySQL, musisz użyć odwrotnego ukośnika, Dangerous: ' i literą Escape Escape: \'. W przypadku MS-SQL rzeczy są zupełnie inne, Dangerous: ' uciekł: ''. Nic nie jest usuwane, gdy w ten sposób unika się danych, to sposób reprezentowania postaci kontrolnej, takiej jak znak zapytania w jej dosłowności.

Oto przykład z użyciem sparametryzowanych kwerend dla MS-SQL i C#, zaczerpnięte z 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 nie jestem świadomy sparametryzowane biblioteki zapytań można wykorzystać. Należy użyć mysql_real_escape_string() lub opointally można użyć tej funkcji .:

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

Rozumiem, że jest to starszy wpis, ale PHP [5.0+] obsługuje sparametryzowane zapytania za pośrednictwem MySQLi (http://php.net/manual/en/book.mysqli.php) i bibliotek PDO (http: // /php.net/manual/en/book.pdo.php). –

+0

@Tieson T. i adodb, a sparametryzowane zapytania to najlepszy wybór. – rook

+1

fyi, mysql_real_escape_string jest przestarzałe –

0

Użyj prawidłowo skonstruowanego obiektu DAL z obiektami SQL Parameter przekazanymi do procedur składowanych i nie musisz się tym martwić. Zaimplementuj obiekty biznesowe i dal, aby streścić dane wejściowe użytkownika na tyle, aby nie były wykonywane jako SQL, ale raczej rozpoznane jako wartości. przykłady są zabawne:

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

Widzę, że polecenia parematerized są do zrobienia, ale twój przykładowy kod nie ma nic wspólnego z nimi! –

+0

@Loren Pechtel: Komentarz mówi, aby ich używać, ale ponadto chcesz, aby Twoi użytkownicy wprowadzili dane wypełniające obiekt biznesowy, taki jak Użytkownik, który działa jako transport do dal, który tworzy polecenia i parametry. Ta abstrakcja oddziela użytkowników od DB o wiele więcej w celu zwiększenia bezpieczeństwa, ponieważ można utworzyć UserValidator i inne podobne rzeczy, aby ich dane wejściowe były nie tylko bezpieczne po wstrzyknięciu SQL, ale również bezpieczne od nieprawidłowych wartości. –

+0

Zgadzam się, że potrzebujesz warstwy, która sprawdza ważność itp., Ale to jest oddzielne od tego, że dusisz się z panem O'Neilem. –

Powiązane problemy