Pytanie:
Jak ograniczyć wpływ i zmniejszyć ryzyko wstrzyknięcia SQL do istniejącej strony internetowej?
Phung D. An
2018-06-21 00:41:53 UTC
view on stackexchange narkive permalink

Nasza strona internetowa jest w 100% oparta na API (z klientem SPA). Niedawno hakerowi udało się zdobyć hasło naszego administratora (zaszyfrowane za pomocą SHA-256) poprzez wstrzyknięcie SQL (i złamanie pwd) w następujący sposób:

  https://example.com/api/products? userId = 3645&type = sqlinject tutaj  

To tylko przykład, ale jest dla nas zabójczy. Na szczęście był to miły haker i właśnie wysłał nam e-mail o włamaniu. Na szczęście strona internetowa jest poddawana ciągłym atakom przez 5 lat istnienia.

Tak, wiemy, że musimy wszędzie sprawdzać dane wejściowe użytkowników i odpowiednio sformatować / uciec / przygotować instrukcję przed wysłaniem danych do MySQL. Wiemy i naprawiamy to. Ale nie mamy wystarczającej liczby programistów / testerów, aby uczynić go w 100% bezpiecznym.

Teraz zakładając, że mamy 0,1% szans na wstrzyknięcie SQL. Jak utrudnić hakerowi znalezienie go i jak najbardziej ograniczyć szkody?

Co robimy, jeśli chodzi o szybkie poprawki / dodatkowe pomiary:

  1. Na wyjściu „gate” współdzielonym przez wszystkie API nie wysyłamy już surowego wyjątku PDOException i wiadomości, jak wcześniej. Ale nadal musimy powiedzieć klientowi, że wystąpił wyjątek:

      {type :ception, code: err643, message: 'contact support for err643'}  

    Wiem, że jeśli haker zobaczy wyjątek, będzie próbował ...

  2. Użytkownik, którego PHP używa do łączenia się z MySQL, może używać CRUD tylko do tabel. Czy to wystarczająco bezpieczne?

  3. Zmień nazwy wszystkich tabel (używamy oprogramowania open source, aby haker mógł odgadnąć nazwy tabel).

Co jeszcze powinniśmy zrobić?

Aktualizacja: ponieważ jest wiele komentarzy, chciałbym podać dodatkowe informacje

  1. Przede wszystkim jest to LEGACY aplikacja, opracowana przez niektórych studentów, a nie klasy korporacyjnej. Nigdzie nie ma zespołu programistów, teraz tylko 1-2 hybrydowych deweloperów obsługujących setki klas Data Access.
  2. Hasło to hash z SHA-256, tak, jest do bani. I zmieniamy to na zalecany sposób php.
  3. Wstrzyknięcie SQL ma 17 lat. Dlaczego nadal istnieje?
  4. Czy przygotowane instrukcje są w 100% bezpieczne przed wstrzyknięciem SQL?
Komentarze nie służą do rozszerzonej dyskusji;ta rozmowa została [przeniesiona do czatu] (https://chat.stackexchange.com/rooms/79300/discussion-on-question-by-phung-d-an-how-to-limit-the-impact-of-i-zmniejsz-the).
Jedenaście odpowiedzi:
Anders
2018-06-21 01:08:04 UTC
view on stackexchange narkive permalink

Nie poświęcaj dużo czasu na obejścia lub połowiczne poprawki. Każda minuta spędzona na próbach implementacji czegokolwiek, co tu sugeruje, to minuta, którą mógłbyś poświęcić na wdrażanie przygotowanych wypowiedzi. To jedyne prawdziwe rozwiązanie.

Jeśli masz lukę w zabezpieczeniach SQLi, atakujący prawdopodobnie w końcu wygra, bez względu na to, co zrobisz, aby ją spowolnić. Więc pamiętaj, że chociaż możesz wprowadzać ulepszenia, w końcu grasz przegraną, chyba że naprawisz główną przyczynę problemu.

Co do tego, co próbowałeś do tej pory: ukrywanie komunikatów o błędach Dobry początek. Zalecałbym zastosowanie jeszcze surowszych uprawnień (patrz poniżej). Jest dyskusyjne, czy zmiana nazw tabel pomoże, ale prawdopodobnie nie zaszkodzi.

Ok, a co z tymi uprawnieniami? Ogranicz możliwości użytkownika bazy danych tak bardzo, jak to możliwe, do poziomu tabeli lub nawet kolumny. Możesz nawet utworzyć wielu użytkowników bazy danych, aby jeszcze bardziej blokować rzeczy. Na przykład, używaj tylko użytkownika bazy danych z uprawnieniem do pisania, kiedy faktycznie piszesz. Łącz się tylko z użytkownikiem, który ma prawo odczytać kolumnę z hasłem, gdy faktycznie musisz przeczytać kolumnę hasła. W ten sposób, jeśli masz lukę umożliwiającą wstrzyknięcie w jakimś innym zapytaniu, nie można jej wykorzystać do wycieku haseł.

Inną opcją jest użycie zapory aplikacji internetowej (WAF), takiej jak mod_security dla Apache. Możesz go skonfigurować tak, aby blokował żądania, które wyglądają podejrzanie. Jednak żaden WAF nie jest doskonały. Konfiguracja wymaga czasu i energii. Prawdopodobnie lepiej wykorzystasz ten czas na implementację przygotowanych oświadczeń.

Ponownie, nie pozwól, aby cokolwiek z tego zwabiło Cię w fałszywe poczucie bezpieczeństwa. Nic nie zastąpi naprawienia głównej przyczyny problemu.

Nie mogę poprzeć ogólnej porady dotyczącej łączenia się tylko z określonym użytkownikiem, gdy potrzebna jest konkretna operacja.Zbyt szybko staje się to niepraktyczne.Jeśli naprawdę chcesz, wystarczy niewielka separacja, na przykład oddzielne zapisywanie w tabelach użytkowników od wszystkiego innego.Ale musisz mieć wszystkie zapytania dotyczące jednego żądania w jednej transakcji.Próba upewnienia się, że tak jest w przypadku każdej możliwej ścieżki kodu, byłaby ogromnym obciążeniem, jeśli masz wielu różnych użytkowników bazy danych.
Generalnie się z tym zgadzam i jest tu dużo dobrego.Nie zgadzam się, że poświęcanie czasu jednemu rozwiązaniu odejmuje czas od innego.Dobry WAF może być skonfigurowany przez osobę systemową, która nie ma konkretnej wiedzy na temat bazy kodu aplikacji.To samo dotyczy zmian w bazie danych, których może dokonać administrator.Chodzi o to, że umiejętności ludzi są bardzo różne, a każda osoba jest przystosowana do różnych zadań.Jeśli potrafisz dobrze wykorzystać umiejętności ludzi, możesz lepiej pracować jako zespół.
_ „Jest dyskusyjne, czy zmiana nazw tabel pomoże, ale prawdopodobnie nie zaszkodzi.” _ - Może to zranić twoich własnych programistów, zaskakując ich za każdym razem, gdy mają dostęp do tabeli, której nazwa nie jest taka, jakiej oczekują.
Od dłuższego czasu korzystam z PDO z przygotowanymi zestawieniami, ale po pewnym czasie staje się to stresujące.Niedawno zacząłem używać [Medoo] (http://medoo.in).To proste, ale potężne opakowanie dla PHP, przydatne dla MySQL, MSSQL, SQLite i nie tylko.Warto się temu przyjrzeć, to naprawdę ułatwia życie, ponieważ nie trzeba już myśleć o przygotowanych wypowiedziach.
@RobinK Jestem bardzo sceptyczny, że używanie przygotowanych instrukcji jest znacznie bardziej „stresujące” niż ręczne łączenie ciągów znaków w każdym miejscu… i, szczerze mówiąc, kogo to obchodzi, skoro programowanie w języku SQL wiąże się z minimalną odpowiedzialnością?Nie jestem pewien, czy po prostu poddanie się i dodanie biblioteki innej firmy zrobi znacznie więcej niż tylko skomplikowanie rzeczy.
Rozważyłbym również zainwestowanie pieniędzy, które powinieneś wykorzystać, aby _ "... ograniczyć wpływ i zmniejszyć ryzyko ..." _, aby zapłacić profesjonalnemu pentestowi (oczywiście, gdy twoi programiści są dość pewni, że wykonali swoją pracę)
trietend
2018-06-21 01:05:50 UTC
view on stackexchange narkive permalink

Jedynym poprawnym sposobem jest użycie przygotowanych instrukcji.

  1. Jeśli ukryjesz komunikaty o błędach, jest to nieco trudniejsze, ale nie powstrzyma to atakujących.
  2. Możesz ograniczyć prawa, ale wszystkie prawa przyznane użytkownikowi mogą uzyskać osoba atakująca. W niektórych przypadkach możliwe jest również wykonanie poleceń powłoki z SQL-Injection.
  3. Zmiana nazw tabel nie pomoże. Narzędzie sqlmap będzie brutalnie wymuszać nazwy tabel dla Ciebie char po znaku. To nie wymaga dużo czasu.

Możesz również ograniczyć liczbę połączeń, aby utrudnić atakującym lub włączyć alerty o podejrzanych połączeniach i zatrzymać tę instrukcję, ale jedynym poprawnym sposobem rozwiązania tego problemu jest użycie przygotowanych instrukcji. Po prostu przejrzyj kod źródłowy i spójrz na instrukcje SQL z dynamiczną zawartością i zamień je.

Uważaj na ograniczenia, ponieważ może to szybko wpłynąć na prawdziwych użytkowników, wiedząc, że problem dotyczy żądania GET, więc może zostać wstrzyknięty w tagu ``, aby wszyscy użytkownicy widzący stronę z tym tagiem wywołali żądanie,i może zostać zablokowany przez witrynę internetową.
Dobrym pomysłem może być również włączenie przeglądu kodu do procesu, np.przejrzyj wszystko, co jest połączone z gałęzią główną lub produkcyjną.Mieć wytyczne dotyczące kodowania, które określają, jak rzeczy powinny być kodowane, a co jest zabronione (np. Nie powinno być dozwolone łączenie parametrów w łańcuchy w zapytaniu SQL).Zapobiegnie to wprowadzaniu nowych luk po naprawieniu obecnych.
Uważam, że „jedyny właściwy sposób” jest nieco imponujący lub w najlepszym przypadku niejednoznaczny.Może użycie bazy danych SQL od początku było błędne?
Ok, mogą istnieć inne opcje, ale jeśli OP już działa zbyt krótko w czasie programowania, te inne sposoby będą po prostu wolniejsze.Przygotowane zestawienia to prawdopodobnie najbardziej praktyczny sposób na zamknięcie dziury.
@phresnel Jakiego rodzaju bazy danych należy użyć zamiast tego?
@curiousguy, ... nie dostajesz iniekcji SQL w bazie danych [Datalog] (https://en.wikipedia.org/wiki/Datalog).Z drugiej strony dzieje się tak dlatego, że ostatnio popularne implementacje ([DataScript] (https://github.com/tonsky/datascript), [Datomic] (https://www.datomic.com/)) używają struktur danych LISPyjako specyfikacje zapytania - nie jako łańcuchy - więc nie ma pokusy, aby próbować budować te zapytania poprzez konkatenację ciągów.
@curiousguy: To zależy od całej platformy i jej wymagań.W przypadku podstawowych wymagań uwierzytelniania i zaledwie kilkudziesięciu tysięcy użytkowników prosta mapa / słownik / tablica asocjacyjna załadowana do pamięci demona / usługi i przechowywana w pliku CSV, XML lub JSON może być właściwą rzeczą.Implementacja tego byłaby prosta lub na przykład użyj CouchDB.Nieskończone możliwości: w zasadzie to tylko struktura danych i wybór algorytmu, chociaż zdaję sobie sprawę, że nawet „licencjat” / „magister” w Niemczech zdaje się zapomnieć o strukturach danych i algorytmach.Na początek: https://bit.ly/2lEy9GL
„Jedyny właściwy sposób” Zdecydowanie nie zgadzam się z „jedynym właściwym sposobem”.Istnieje wiele sposobów korygowania sposobów.(W końcu robią coś równoważnego.)
Gloweye
2018-06-21 15:23:55 UTC
view on stackexchange narkive permalink

Wiemy, ale nie mamy wystarczającej liczby programistów / testerów, aby zapewnić 100% bezpieczeństwo.

To jest prawdziwy problem . Dopóki nie zatrudnisz większej liczby osób lub nie zmienisz priorytetów, nie jesteś bezpieczny. Zatrzymanie 99,9% napastników oznacza, że ​​Twoje dane zostały naruszone. Rozwiązania pomocnicze są złe i nie działają . Nie trać czasu na refaktoryzację wzorca dostępu SQL, podczas gdy możesz naprawiać rzeczywiste problemy.

Jeśli chodzi o rozwiązanie kodu, użycie przygotowanych instrukcji, jak sugeruje wiele osób, jest najłatwiejszym sposobem bezpiecznego korzystania z SQL.

Jest to o wiele łatwiejsze niż próba użycia php do samodzielnego czyszczenia argumentów i kosztuje o wiele mniej czasu. Po prostu przeszukaj całą bazę kodu dla wszystkiego, co dotyczy SQL, i napraw to.

Nie sądzę, by zatrudnienie większej liczby osób pomogło jako [rozwiązanie krótkoterminowe] (https://softwareengineering.stackexchange.com/questions/14968/why-does-adding-more-resource-to-a-late-project-make-it-later).A obawy dotyczące bezpieczeństwa wymagają natychmiastowych rozwiązań.Twoje inne sugestie są trafne.
@xDaizu i Jacco: dziękujemy za zainteresowanie.mamy tysiące starszych klas dostępu do danych, ale tylko 1-2 programistów do naprawiania rzeczy, zrobimy „przygotowane oświadczenia”, ale po prostu nie jesteśmy w 100% pewni
@xDaizu Chociaż zwykle jestem zdecydowanym zwolennikiem idei, że nie można wciągnąć większej liczby osób do późnego projektu, aby go przyspieszyć, znalezienie osób, które potrafią przetłumaczyć SQL na przygotowane instrukcje, jest stosunkowo łatwe, ponieważ jest to dość podstawowa i uniwersalna umiejętność dlaw większości.
Zatrudnianie wielu osób późno może być generalnie złe, ale jak powiedział @wedstrom, samo tłumaczenie na przygotowane oświadczenia powinno być czymś, co ludzie, którzy odpowiadają na ofertę pracy w PHP, mogą zrobić bez większego wprowadzenia.Po tym może nastąpić właściwe wprowadzenie.Na przykład, refaktoryzuj kod, aż uzyskasz tysiące starszych klas dostępu do danych ze wspólną nadklasą, która zawiera wszystkie podstawy SQL.
Nacht
2018-06-21 10:37:33 UTC
view on stackexchange narkive permalink

Usuń na zawsze cały kod SQL z kodu

Najlepszym rozwiązaniem tego problemu jest usunięcie całego kodu SQL w postaci ciągów literałów z kodu i nigdy więcej nie wprowadzaj go. Zamiast tego użyj oprogramowania ORM, takiego jak Hibernate lub Entity Framework. To oprogramowanie jest i tak o wiele przyjemniejsze w użyciu niż surowy SQL i automatycznie parametryzuje SQL, gdy ostatecznie trafia do bazy danych. Jeśli to możliwe, miej tę politykę.

Jeśli nie masz czasu na naukę i implementację tych pakietów lub nie możesz ich użyć z innego powodu, odpowiedź trietendy jest następną najlepszą rzeczą, używając przygotowane oświadczenia. Pozwoli to zabezpieczyć się przed iniekcją SQL. Oznacza to, że dopóki nie wywiążesz presji na programistów, aby dostarczali szybkie rozwiązania, wtedy mogą ponownie zapomnieć o parametryzacji jednej zmiennej, pozostawiając Cię z powrotem tam, gdzie zacząłeś.

To może być dobra rada dotycząca bezpieczeństwa, ale jest to ** okropna ** rada dotycząca programowania.ORMy NIE są srebrną kulą, a używanie ORM może łatwo prowadzić do problemów z wydajnością.Widziałem, jak ORM wyciągał pełną tabelę w pamięci i wykonywał filtry w pamięci, ponieważ nie zdołał obniżyć ich do SQL.Widziałem również użytkowników ORM, którzy nieumyślnie wykonali zapytanie w pętli (ponieważ wyglądało to jak kod!).Więc nie, ORMy nie są srebrną kulą ... i dla jakichkolwiek pół-poważnych aplikacji polecałbym używać dobrego frameworka SQL.
@MatthieuM.brak wiedzy, jak korzystać z technologii, nie jest wymówką, aby nigdy jej nie używać.ORMy, jak każde inne narzędzie, podlegają zastrzeżeniom i krzywej uczenia się, i zapewniam Cię, że doskonale nadają się do „półpoważnych aplikacji”, jeśli są używane prawidłowo.
@BgrWorker: Jest to bardziej kwestia nieszczelnej abstrakcji niż kwestia wiedzy.W rzeczywistości użycie ORM jest bardzo łatwe iw większości sytuacji będzie działać dobrze.Wtedy, nagle, „niewinna” refaktoryzacja wprowadzi problem z wydajnością z różnych powodów ... ale testy funkcjonalne przejdą, ponieważ nadal są poprawne (po prostu wykonują dużo niepotrzebnej pracy).Dlatego wolę dobry framework SQL: podkreśla różnicę między tanim getter i kosztownym zapytaniem SQL, a także jasno określa, które części kodu opierają się na połączeniu SQL.
Myślę, że „najlepsze” jest zbyt bezwzględne.Może SQL nie jest w ogóle uzasadniony?
@MatthieuM.Niewinna refaktoryzacja kodu SQL może również powodować problemy z wydajnością, jeśli uniemożliwia użycie indeksów.
@AndrolGenhald: Tak, podobnie jak rozbieżności w strukturze tabel między środowiskami programistycznymi / testowymi / produkcyjnymi i niezliczonymi zmiennymi.Jednak główną zaletą frameworka SQL zamiast ORM jest to, że w przeglądzie kodu od razu widać, że dotykasz SQL: które tabele, które zapytania itp ... w przeciwieństwie do ORMów, ponieważ wygląda tak bardzo jak kodłatwo to przeoczyć.
Jeśli OP ma problemy z prawidłowym wykorzystaniem swojej obecnej technologii, przejście na nową zajmie jeszcze więcej czasu.Najpierw zabezpiecz witrynę tak szybko, jak to możliwe.Po drugie, kiedy jest więcej czasu, zbadaj, jaka technologia jest najlepsza na przyszłość.Wszystkie rozwiązania technologiczne mają wady i zalety.Każdy, kto mówi inaczej, próbuje ci coś sprzedać.
@MatthieuM.Dlaczego ORMy nie są srebrną kulą do wstrzykiwania SQL, o co chodzi w tym pytaniu?
Co więcej, czy wolisz mieć stronę internetową, której ładowanie trwa 30 sekund, czy też Twoje dane wyciekły do całego Internetu?Jeden z tych problemów można naprawić;drugi nie.
ORMy @Nacht: nie są srebrną kulą z * rozwoju * punktu widzenia.Mogą rozwiązać konkretny problem iniekcji SQL, ale nie rozwiązują wszystkich problemów.Jeśli chodzi o twoje pytanie słomika: oba problemy można naprawić i żaden nie jest nieunikniony.Dobry framework SQL * również * unika iniekcji SQL (ponieważ zapytania SQL nie są łańcuchami), jednocześnie pokazując, gdzie zachodzą interakcje z bazą danych i jakie zapytania są wykonywane.
@Nacht Większość ORMów ma własny język zapytań, np.HQL.Oto przykład CVE dla ataku polegającego na iniekcji HQL.[„Ataki typu„ Hibernate Query Language ”(HQL) i uzyskiwanie poufnych informacji za pośrednictwem parametru entityName.”] (Https://nvd.nist.gov/vuln/detail/CVE-2016-1595).Jeśli wszystko, co musisz zrobić, to zmienić SQLi na HQLi, nie jestem pewien, czy to naprawdę coś rozwiązuje.
@AndrolGenhald Refaktoryzacja do przygotowanych instrukcji nie wymaga refaktoryzacji SQL.Często może to poprawić wydajność, ponieważ instrukcje nie są ponownie kompilowane w bazie danych przy każdym wykonaniu.To, co staje się trudne, to złożona logika w próbie dynamicznego generowania różnych instrukcji (np. Dołączanie różnych klauzul where) na podstawie różnych warunków.Ibatis ma do tego przyzwoite rozwiązanie za pomocą szablonów i generuje przygotowane zestawienie dla każdego wykonywanego zapytania.
@Nacht Oto lepszy przykład tego, jak ORM nie jest `` srebrną kulą do wstrzykiwania SQL '', który omawia, jak to może się zdarzyć: https://cwe.mitre.org/data/definitions/564.html
@JimmyJames Nie próbowałem sugerować, że refaktoryzacja SQL będzie wymagana, przedstawiłem kontrapunkt do twierdzenia MatthieuM, że niewinna refaktoryzacja może powodować problemy z wydajnością podczas korzystania z ORM.
@AndrolGenhald Moje doświadczenie z ciężkimi ORMami jest takie, że próba użycia ich z bazą danych, która nie została zaprojektowana do pracy z nimi, jest problematyczna.Naprawdę trudno jest go zaimplementować bez pewnego poziomu lub refaktoryzacji kodu, struktur bazy danych i / lub zapytań.Refaktoryzacja w celu użycia gotowych instrukcji * może * zdecydowanie odbyć się bez zmiany struktury któregokolwiek z nich, ale poziom wysiłku będzie różny.
@JimmyJames Znowu nie to, co mówiłem.Po prostu powiedziałem, że argumentowanie przeciwko używaniu ORM, ponieważ "spowoduje to problemy z wydajnością", niekoniecznie jest dobrym argumentem, ponieważ problemy z wydajnością mogą się zdarzyć również bezpośrednio przy użyciu SQL.
@AndrolGenhald Czy to najsilniejszy argument za nie ruszaniem się?Może nie, ale OP ma już SQL.Przejście na ORM raczej nie będzie spadkiem w zastępstwie, jeśli zmiana na przygotowane oświadczenia mniej więcej to.W moim (w dużej mierze ujednoliconym) oszacowaniu jest znacznie bardziej prawdopodobne, że PO wprowadzi zmiany w planach wykonania, gdy przejdzie na ORM, niż podczas refaktoryzacji w celu użycia przygotowanych oświadczeń.
@JimmyJames pozwól nam [kontynuować to na czacie] (https://chat.stackexchange.com/rooms/79246/)
Jared Smith
2018-06-21 19:18:37 UTC
view on stackexchange narkive permalink

Wiemy, ale nie mamy wystarczającej liczby programistów / testerów, aby uczynić go w 100% bezpiecznym.

Nie jest do końca jasne, co masz na myśli przez to oświadczenie, ponieważ zostało przygotowane instrukcje są trywialne w każdym popularnym języku sieciowym (PHP, Python, Java, node.js itp.) i są mniej więcej w 100% skutecznym środkiem przeciwko iniekcji SQL.

Czy masz na myśli podzlecanie i nie możesz sobie pozwolić na kontrolę jakości kodu, który piszą dla Ciebie na podstawie umowy? Nie możesz sobie pozwolić, aby tego nie robić: nadal jesteś tutaj odpowiedzialną stroną.

Czy masz na myśli, że twoi programiści są zbyt zajęci wdrażaniem funkcji, aby aktualizacja kodu źródłowego zajęła kilka godzin? Wszystko inne niż przygotowane oświadczenia zajmie więcej czasu i będzie kosztować więcej (np. ORM, zaciemnianie, szczegółowe uprawnienia itp.).

Czy masz na myśli, że twoi programiści nie są wystarczająco kompetentni, aby wykonać to proste zadanie? To chyba większy problem (a ściślej mówiąc, wstrzyknięcie SQL nie powinno być Twoim największym zmartwieniem w tym momencie).

Czy masz na myśli, że twoją bazą kodową jest taki spaghetti-logiczny bałagan w formacie shotgun z zagnieżdżonymi include s, których wykonanie nawet kompetentnym programistom zajmie wieczność, co w innym przypadku byłoby prostym zadaniem trwającym kilka godzin? Podobnie, większy problem.

Ktokolwiek to jest, rozwiązaniem jest użycie przygotowanych wyciągów, około wczoraj.

Mam na myśli tysiące starszych klas dostępu do danych, ale tylko 1-2 programistów, którzy naprawią rzeczy, zrobimy „przygotowane oświadczenia”, ale nie mamy 100% pewności.No dalej, nawet Facebook ma lukę w zabezpieczeniach
@PhungD. Przepraszam, to trudne.1000 miejsc do zmiany dla 1-2 deweloperów nie jest tak trywialne, jak w przypadku rozsądniejszej architektury.Ale nadal jest to wykonalne, tylko w ciągu dni (np. 1-2) zamiast godzin.Jeśli chodzi o 100% pewności, powinieneś być całkiem pewien, że wystarczy uruchomić polecenie `grep` w swojej bazie kodu, ale jeśli zostaniesz pozwany,„ byliśmy zajęci i brzmiało to ciężko ”, nie będzie to bardzo wiarygodna obrona ... tak samo jak„jakiś facet na uniwersytecie poprosił o wszystkie nasze dane użytkownika, a my mu je przekazaliśmy i zaufaliśmy, że nie będzie ich sprzedawać - będzie na fb.
@PhungD.An Duży problem z przejściem od konkatenacji łańcuchów do SQL do gotowych instrukcji polega na tym, że zorientowanie się, co robi istniejący bałagan, zajmuje trochę czasu.Czas poświęcony na naprawienie tego problemu: poprawi bezpieczeństwo, poprawi wydajność i sprawi, że kod będzie łatwiejszy do zrozumienia.Próba oczyszczenia danych wejściowych to niekończące się zadanie, które nigdy nie rozwiąże problemu głównego i nie poprawi podstawy kodu.
@PhungD. Luki w zabezpieczeniach mogą i _ będą_ stać się dla Ciebie bardzo kosztowne, jeśli kiedykolwiek zostaną wykorzystane.Znacznie droższe niż jakikolwiek czas lub pieniądze, które według Ciebie oszczędzasz, nie postępując właściwie.
Nicolas
2018-06-21 23:02:45 UTC
view on stackexchange narkive permalink

Po wdrożeniu wstępnej porady dotyczącej "przygotowanej instrukcji", polecam poczytać o wstrzykiwaniu SQL. Pytanie „jak zapobiec iniekcji SQL” to dość szerokie pytanie! Bezpieczeństwo to temat, z którym Ty (a raczej cały Twój zespół programistów) musicie się bardzo dobrze zapoznać, aby zmniejszyć ryzyko kompromisu. Jedna dziura podważa wszystkie twoje inne wysiłki.

Odwiedź Open Web Application Security Project (OWASP) tutaj: https://www.owasp.org/index.php/SQL_Injection

W szczególności materiał dodatkowy:

  • Ściągawka dotycząca zapobiegania iniekcjom SQL
  • Ściągawka dotycząca parametryzacji zapytań
  • Artykuł przewodnika na temat unikania luk w zabezpieczeniach związanych z iniekcją SQL

A także

  • Jak przejrzeć kod pod kątem luk w zabezpieczeniach związanych z iniekcją SQL .
Uwielbiam OWASP za zrozumienie, dlaczego postępujesz właściwie, ale istnieje wiele innych zasobów, które są specyficzne dla stosu technologii OP, od których łatwiej jest zacząć.Podobnie jak w przypadku wielu problemów związanych z bezpieczeństwem, najlepiej jest nie odkrywać koła na nowo.Najlepszym początkiem są podstawowe praktyki bezpieczeństwa wybranej technologii.
W rzeczywistości, jak zapobiec iniekcji SQL, jest bardzo wąskim pytaniem z bardzo prostą odpowiedzią: nie konstruuj ciągów zapytań z danych kontrolowanych przez użytkownika.Uniknięcie tego w pierwszej kolejności jest dość łatwe, ale oczywiście znalezienie miejsc, które to robią w dużej istniejącej bazie kodu, może być trudne.
@Cubic W porządku, samo pytanie PO było wąskie.Być może czytałem poza samym pytaniem: jeśli ktoś zadaje tego typu pytanie, wydaje się, że to, czego faktycznie potrzebuje, to uzyskanie ogólnego zrozumienia najlepszych praktyk.(i, jak powiedział powyżej Guy Schalat, najlepsze praktyki dotyczące _Twojej technologii_)
CoderTao
2018-06-22 02:17:28 UTC
view on stackexchange narkive permalink

Rozwiązaniem tymczasowym byłoby przyjrzenie się zaporze aplikacji internetowej (WAF) - jest kilka firm, które zapewniają to jako usługę, i kilku dostawców chmury, którzy również mają swoje oferty. Wydaje się, że CloudFlare oferuje jeden, miałem jednego klienta używającego Incapsula i wiem, że oferta AWS WAF ma kilka zarządzanych zestawów reguł do wstrzykiwania SQL.

Sposób, w jaki to działa, polega na tym, że cały ruch jest wysyłany do / przez WAF (albo przez włączenie go na serwerach, albo ustawienie DNS tak, aby wskazywał na WAF, tak jak w przypadku CDN) i szuka rzeczy które wyglądają jak próby wstrzyknięcia SQL w parametrach. Nie przechwytuje wszystkich ataków i może blokować legalny ruch, ale jest to dostępna poprawka.

+1 za faktyczne odpowiadanie na Q i nie powtarzanie tego, co zostało już powiedziane o oczyszczaniu danych wejściowych przez użytkownika.Oczywiście przygotowane instrukcje powinny zostać zaimplementowane, ale w zależności od s / w uruchomienie WAF może być znacznie szybsze, może nie być idealnym rozwiązaniem, ale prawdopodobnie pomoże w natychmiastowej sytuacji.
Concrete Gannet
2018-06-22 08:28:22 UTC
view on stackexchange narkive permalink

Rozumiem, że przez „nie ma wystarczającej liczby programistów” masz na myśli, że niektórzy wpływowi ludzie w Twojej organizacji uważają, że istnieją wyższe priorytety, więc wszelkie zasoby, które masz, są przeznaczone na te rzeczy. Zatem naprawienie problemu z bezpieczeństwem jest przegraną na rzecz innych rzeczy w analizie kosztów i korzyści.

Twoim zadaniem jest tutaj zmiana zdania, tak samo jak wdrożenie poprawki. Określ ilościowo, o co toczy się gra - jaka byłaby szkoda, zarówno pod względem finansowym, jak i reputacyjnym, w przypadku kolejnego naruszenia? W Twojej jurysdykcji mogą obowiązywać przepisy, które wymagają zgłaszania naruszeń danych użytkownika. Czy to byłoby żenujące? Czy media mogą donosić o złych praktykach Twojej organizacji?

Pomyśl o inwestycji polegającej na naprawie zabezpieczeń jako o ubezpieczeniu. Z perspektywy czasu, gdy wiesz, że Twój budynek nie spłonął przez okres dziesięciu lat, możesz argumentować, że Twoje składki były stratą. Ale Ty i Twoja organizacja płacicie za ubezpieczenie, ponieważ czeka was niepewna przyszłość. To zarządzanie ryzykiem.

Ryzyko ma dwa czynniki: prawdopodobieństwo i wpływ. Prawdopodobieństwo kolejnego naruszenia jest wysokie - wiesz, że może i zostało zrobione przynajmniej raz. Jeśli potencjalne konsekwencje są również złe, powinieneś zwiększyć priorytet naprawy swoich luk w zabezpieczeniach.

LUser
2018-06-23 16:53:53 UTC
view on stackexchange narkive permalink

Jak wszyscy wspominali, napraw kod na stronie.

Możesz zrobić dowolne łaty na ścianie, ale dopóki ściana nie zostanie poprawnie zbudowana, wszelkie łaty będą stanowić przeszkodę dla problemu krwawienia.

Każda inna sugestia dotycząca czyszczenia kodu jest tym, co Linus Torvalds nazwałby masterbation.

  • Napraw kod (z najbardziej oczywistych punktów wtrysku do ostatnich parametrów IE Get) i użyj przygotowanych instrukcji. jak mogę zapobiec iniekcji sql w php

    • Możesz wypróbować WAF (IE ModSecurity ) tymczasowo, dopóki nie będziesz w stanie naprawić.

    • Spróbuj Być może jakiś rodzaj blokady adresu IP dla „osób testujących witrynę” lub blokujących wykonywanie niebezpiecznych zapytań.

    • Jeśli masz możliwość utworzenia tymczasowego (bezpiecznego) ekranu logowania z przodu, dopóki ten problem nie zostanie rozwiązany.

    • Wypróbuj usługę innej firmy, dopóki problem nie zostanie rozwiązany, na przykład Cloudflare lub cokolwiek innego tam.

PDO są dostępne od PHP 5.1 wypuszczonego 24 listopada 2005 ... Twórcy muszą zrozumieć, że mają one konsekwencje ich kiepskie nawyki w zakresie kodowania i osobiście uważam, że za jakość wykonywanej pracy należy odpowiadać.

W każdym razie PDO są łatwe do wdrożenia. Jeśli twoi programiści nie są w stanie zapewnić lepszej jakości, sugerowałbym czyszczenie ...

bobflux
2018-06-24 00:05:31 UTC
view on stackexchange narkive permalink

Najważniejsza zasada to:

Używaj bibliotek, narzędzi i interfejsów API, które sprawiają, że opcja bezpieczna jest najłatwiejsza.

Nacht mówi „po prostu użyj ORM ”, który jest podzbiorem tej reguły.

Gotowe instrukcje naruszają tę zasadę, ponieważ są niewygodne w użyciu, powodują rozdęcie kodu, a także często mogą być wolniejsze niż instrukcje nieprzygotowane, w zależności od Baza danych. Są dobrym rozwiązaniem, nie będę krytykować nikogo, kto ich używa, ale niekoniecznie są one najlepszym i najwygodniejszym rozwiązaniem.

I ... chcemy, aby opcja bezpieczna była łatwa i wygodna, dlatego programista używa go dla własnego interesu i lenistwa. Chcemy, aby programista musiał zejść mu z drogi i włożyć trochę wysiłku, aby użyć niebezpiecznej opcji! ...

O wiele lepszym rozwiązaniem jest API, takie jak Python dbapi. Napisałem odpowiednik php lata temu, który wyglądał tak:

  db_query ("SELECT * FROM mytable WHERE id =% s", $ id)  

Jest to wygodniejsze niż przygotowane oświadczenia. Tylko jeden wiersz do wpisania. Zwraca również wynik w postaci, której może używać foreach (), więc jest dużo łatwiejszy w użyciu niż fetch () i takie tam. Co ważniejsze, kod ukryty za tym interfejsem API będzie poprawnie obsługiwał ucieczkę. To sprawia, że ​​iniekcje SQL są nieistotne. Obsługuje około 99% zapytań, jeśli nie używasz ORM. Dynamiczne zapytania (zwykle wyszukiwanie) będą jednak wymagały specjalnej obsługi, ale nadal jest to łatwe.

Jeśli będziesz pamiętać o tej zasadzie, w pewnym momencie będziesz musiał się zastanawiać, dlaczego musisz używać htmlspecialchars (), i dlaczego język nie ma funkcji, która sprawiłaby, że ustawienie bezpieczne (tj. brak wulgaryzmów XSS) byłoby najłatwiejsze w użyciu? Dlaczego oh dlaczego? I wtedy upuszczasz PHP.

Tom
2018-07-06 15:17:25 UTC
view on stackexchange narkive permalink

Oprócz wszystkich świetnych dotychczas odpowiedzi, jeśli chcesz rozwiązać specyficzny problem z wyodrębnianiem danych logowania użytkownika, możesz zmienić swoją bazę danych tak, aby hasła znajdowały się w osobnej tabeli ze ścisłymi prawami dostępu , podobnie do sposobu, w jaki systemy uniksowe umieszczają je w /etc/shadow.

Aby zweryfikować poświadczenia, potrzebujesz procedury składowanej, która przyjmuje wprowadzone hasło (lub hash) jako parametr i zwraca wartość logiczną. Innymi słowy, odciążasz zadanie weryfikacji poświadczeń w bazie danych, a rzeczywisty hash nigdy nie opuszcza bazy danych.

Wymaga to minimalnej refaktoryzacji i rozwiązuje natychmiastowy problem u źródła, zamiast jednego konkretnego wstrzyknięcia SQL, podczas gdy pozostawiając cię bezbronnym na następny.

Chociaż na początku wydaje się to dobrym pomysłem, większość baz danych nie obsługuje dobrych funkcji haszowania haseł, a zapytania do bazy danych są często rejestrowane.Przypuszczam, że pobierasz _ just_ sól i parametry, hash, a następnie wykonujesz inne zapytanie, aby porównać hash, ale wydaje się to zbyt skomplikowane, aby było tego warte dla większości witryn.
na przykład jest pgcrypto dla PostgreSQL.Nie wiem o innych bazach danych.Nie mogę sobie wyobrazić, że rzeczy takie jak Oracle nie mają odpowiedników.


To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 4.0, w ramach której jest rozpowszechniana.
Loading...