2009-03-25 10 views
25

Stworzyłem małą stronę ankietową w naszej intranecie. Ta strona internetowa nie jest dostępna z zewnątrz.SQL injection na INSERT

Formularz to po prostu kilka przycisków opcji i uwagi.

Chciałbym zachować dobre praktyki kodowania i chciałbym chronić się przed iniekcjami SQL.

Czy iniekcje SQL mogą się zdarzyć w instrukcji wstawiania z komentarzami z pola tekstowego? Jeśli tak, jak mogę się przed nim zabezpieczyć przy użyciu .NET 2.0?

+0

Informacje dodatkowe: Podczas tworzenia strony internetowej nie skupiaj się tylko na wtrysku sql. Sprawdź również niebezpieczeństwo XSS przed wstawieniem go do bazy danych. Czy każdy kod wyjściowy jest zabezpieczony przez Server.HtmlEncode (...)? –

Odpowiedz

54

Wstrzyknięcie może się zdarzyć w przypadku nieprawidłowego uruchomienia instrukcji SQL.

Na przykład udawajmy, że Twoja tabela komentarzy zawiera dwa pola, identyfikator liczby całkowitej i ciąg komentarza. Więc bym INSERT następująco:

INSERT INTO COMMENTS VALUES(122,'I like this website'); 

Rozważmy kogoś wprowadzając następującą opinię:

'); DELETE FROM users; -- 

Jeśli wystarczy umieścić komentarz ciąg w SQL bez spodowało to może włączyć się do jednego INSERT następujące dwa oświadczenia z komentarzem:

INSERT INTO COMMENTS VALUES(123,''); DELETE FROM users; -- '); 

To usunąć wszystko od stolika users. I są ludzie, którzy chcą spędzić cały dzień na szukaniu odpowiedniego tablename do opróżnienia przy użyciu prób i błędów oraz różnych sztuczek. Aby uniknąć tego problemu, należy użyć parameterized SQL statements.

I to nie tylko ze względów bezpieczeństwa. Na przykład, jeśli tworzysz swoje SQL naiwnie następujący komentarz:

I'm just loving this website 

spowoduje błąd składni SQL powodu apostrofu interpretowane przez SQL jako zamknięcia cytatu.

+2

ładny punkt na apostrofie - Używałem metody string.replace - ale widzę, że jest to znacznie łatwiejsze. – Brad

+0

Bardzo dobrze wyjaśnione. Ładnie wykonane. –

+1

Nawet nazwa może spowodować problem, jeśli nie zostanie wykonany jako parametr, np. O'Tool, O'Rourke. – Martin

27

Użyj sparametryzowanych zapytań, aby tekst był automatycznie cytowany.

SqlCommand command = connection.CreateCommand(); 
command.CommandText = "insert into dbo.Table (val1,val2,txt) values (@val1,@val2,@txt)"; 
command.AddParameterWithValue("val1", value1); 
command.AddParameterWithValue("val2", value2); 
command.AddParameterWithValue("txt", text); 

... 
-4

Najprostszym sposobem ochrony przed tą formą SQL injection jest raczej używanie parametrów i procedur przechowywanych niż budowanie instrukcji SQL. (W języku C# lub wewnętrznie do SQL Server).

Jednak nie jestem do końca pewien, czy powinieneś spędzać z tym czas, chyba że to oczywiście twoja polityka korporacyjna, ponieważ szanse na to, że kiedykolwiek się pojawią, są w najlepszym razie minimalne, a jeśli do tego dojdzie, mam nadzieję, że natychmiast wiedziałbym, kto to jest.

+0

Oczywiście niezadowolony pracownik nigdy nie próbowałby wciągnąć bazy danych twojej firmy. ZAWSZE musisz martwić się o bezpieczeństwo i stosować najlepsze praktyki. – tvanfosson

+0

Nie zgadzam się. Jest to wewnętrzna strona internetowa, do której każdy były pracownik nie powinien mieć dostępu. Również zgaduję (lub na pewno mam nadzieję), że cały ruch wewnętrzny jest rejestrowany. Potrzeby bezpieczeństwa, muszą zostać ocenione wspólnie z innymi krytykami i mogą nie być uzasadnione w wielu sytuacjach. – Bravax

+0

Kto powiedział, że musisz być byłym pracownikiem, który jest niezadowolony? Dobre zabezpieczenie zapobiega uszkodzeniom, nie przypisując później winy. W takim przypadku koszt użycia sparametryzowanych zapytań nie jest nawet bardzo wysoki. Powinna to być norma przy ręcznym konstruowaniu zapytań. – tvanfosson

0

Tak, może.Załóżmy, że klient wysyła to:

OR 1 = 1 

To może być bardzo bolesne dla

SELECT * FROM admin WHERE name = @name AND password = @password 

Można temu zapobiec z

+0

Pytanie dotyczyło wyraźnie instrukcji INSERT. –

+0

prawda. ale może lista pomaga – boj

0

Tak, mogą się zdarzyć. Najprostszym sposobem zabezpieczenia się przed tym jest użycie przygotowanych instrukcji zamiast ręcznego budowania kodu SQL.

Więc zamiast tego:

String sql = 
String.Format("INSERT INTO mytable (text_column) VALUES ('{0}')", 
    myTextBox.Text); // Unsafe! 

można byłoby zrobić coś takiego:

String sql = "INSERT INTO mytable (text_column) VALUES (?)"; // Much safer 

Następnie dodać tekst w polu tekstowym jako parametr do swojej DbCommand który spowoduje jej automatycznie uciekać i zastąpić "?" w SQL.

0

Oprócz korzystania z przygotowanych sprawozdań i parametry niż łączenie ciągów w swojej SQL należy również wykonać następujące czynności:

  1. walidacji i użytkownik format wejściowy po stronie serwera. Sprawdzanie poprawności i ograniczenia po stronie klienta można łatwo ominąć za pomocą narzędzi takich jak WebScarab lub podszywając się pod formularz.

  2. Skonfiguruj odpowiednie uprawnienia dla konta użytkownika bazy danych. Aplikacja internetowa powinna używać oddzielnego konta lub roli w bazie danych z uprawnieniami ograniczonymi tylko do tabel, widoków i procedur wymaganych do uruchomienia aplikacji. Upewnij się, że użytkownik nie ma wybranych uprawnień w tabelach systemowych. Ukryj szczegółowe komunikaty o błędach od użytkowników i używaj mniej popularnych nazw dla swoich obiektów. Zadziwia mnie, jak często można określić typ serwera (Oracle, mysql, sqlserver) i znaleźć podstawowe informacje o schemacie w komunikacie o błędzie, a następnie uzyskać informacje z tabel o nazwie "użytkownik (s)", "pracownik (s)". Jeśli nie ustawić uprawnienia jak w (2) i mogę określić swój typ serwera jesteś otwarty na wypowiedzi jak ta dla SQL Server

    SELECT nazwa_tabeli FROM information_schema.table

    EXECUTE sp_help foundTableName

3

Wstrzyknięcie SQL może się zdarzyć za każdym razem, gdy przekażesz zapytanie do bazy danych. Oto prosty przykład:

SQL Injection Explained

Kluczem ciągu .NET to zrobić jak dał Dave Webb. Zapobiegnie to próbie wstrzyknięcia, obejmując cały ciąg jako jeden parametr, który zostanie przesłany, obsługując wszystkie znaki, które mogą być interpretowane przez SQL Server w celu zmiany zapytania lub dołączenia dodatkowych poleceń.

Należy podkreślić, że iniekcja SQL może wystąpić w dowolnej aplikacji, a nie tylko w aplikacjach internetowych. A wewnętrzny atak jest zazwyczaj najbardziej kosztowny dla organizacji. Nie można bezpiecznie założyć, że atak nie będzie pochodził z wewnątrz.

0

Zapobiegaj iniekcji SQL za pomocą przygotowanej instrukcji. Zastosowanie placehoder (?) Całkowicie eliminuje lukę w sql Injection. przykład String sql = Wybierz * z user_table gdzie username = '+ request.getparameter ("username") +'; statement.executeQuery (sql);

powyższe stwierdzenie jest podatna na SQL injection.

Aby zapewnić bezpieczeństwo przed wstrzyknięciem sql. Skorzystaj z następującego fragmentu kodu:

String sql = Wybierz * z user_table gdzie username = ?; statement.setString (1, nazwa użytkownika);

+0

Składnia '?' nie działa dla wszystkich dostawców/DB. –