2008-11-10 14 views
5

Zapytanie "statyczne" to takie, które pozostaje takie samo przez cały czas. Na przykład przycisk "Tagi" na Stackoverflow lub przycisk "7 dni" na Digg. W skrócie, zawsze mapują one do konkretnego zapytania bazy danych, dzięki czemu można je utworzyć w czasie projektowania.Tworzenie zapytań dynamicznych i bezpiecznych

Ale staram się dowiedzieć, jak wykonać "dynamiczne" zapytania, w których użytkownik w zasadzie dyktuje, w jaki sposób zapytanie bazy danych zostanie utworzone w środowisku wykonawczym. Na przykład w Stackoverflow możesz łączyć znaczniki i filtrować posty w wybrany sposób. To zapytanie dynamiczne, ale bardzo proste, ponieważ to, co można połączyć, znajduje się w świecie tagów. Bardziej skomplikowanym przykładem jest możliwość łączenia tagów i użytkowników.

Przede wszystkim, gdy masz zapytanie dynamiczne, brzmi to tak, jakby nie można było już używać api api, aby uniknąć iniekcji sql, ponieważ elementy zapytania będą zależeć od tego, co użytkownik zdecydował się uwzględnić w zapytaniu. Nie widzę, jak inaczej budować to zapytanie, niż przy użyciu dołączania ciągów.

Po drugie, zapytanie może potencjalnie obejmować wiele tabel. Na przykład, jeśli SO pozwala użytkownikom filtrować w oparciu o użytkowników i znaczniki, a te prawdopodobnie żyją w dwóch różnych tabelach, budowanie zapytania staje się nieco bardziej skomplikowane niż tylko dołączanie kolumn i klauzul WHERE.

Jak mogę wdrożyć coś takiego?

+0

Aby zasugerować abstrahowanie: W jakim języku rozmawiasz z bazą danych? Z której bazy danych korzystasz? –

+0

Twoja baza danych jest bardzo ważna. Które RDBMS? Po drugie, czy w ogóle chcesz ograniczyć. Czy chcesz powiedzieć, że możesz wyszukiwać tylko na 10 tagach ... 11 to verboten? –

Odpowiedz

0

Cóż, opcje muszą być odwzorowane na coś.

Ciąg zapytania SQL CONCAT nie stanowi problemu, jeśli nadal używasz parametrów dla opcji.

2

Pierwszą zasadą jest to, że użytkownicy mogą określić wartości w wyrażeniach SQL, ale nie SQL składni. Cała składnia zapytania powinna być dosłownie określona przez twój kod, a nie przez użytkownika. Wartości określone przez użytkownika mogą być dostarczone do SQL jako parametry zapytania. Jest to najskuteczniejszy sposób ograniczenia ryzyka wstrzyknięcia SQL.

Wiele aplikacji musi "budować" kwerendy SQL za pomocą kodu, ponieważ, jak wskazujesz, niektóre wyrażenia, łączenia tabel, porządek według kryteriów itd. Zależą od wyborów użytkownika. Podczas budowania zapytania SQL kawałek po kawałku, czasami trudno jest zapewnić, że wynik jest poprawną składnią SQL.

Pracowałem na klasie PHP o nazwie Zend_Db_Select, która zapewnia interfejs API, aby pomóc w tym. Jeśli lubisz PHP, możesz spojrzeć na ten kod pomysłów. Nie obsługuje żadnego zapytania, jakie można sobie wyobrazić, ale robi dużo.

Niektóre inne frameworki baz danych PHP mają podobne rozwiązania.

1

Chociaż nie jest to ogólne rozwiązanie, oto kilka kroków, które można podjąć w celu złagodzenia dynamicznego, a jednocześnie bezpiecznego problemu z zapytaniami.

Kryteria, w których wartość kolumny należy do zestawu wartości, których zasadność jest arbitralna, nie muszą być dynamiczne. Rozważ skorzystanie z funkcji instr lub użycie specjalnego stołu filtracyjnego, z którym łączysz się. To podejście można łatwo rozszerzyć na wiele kolumn, o ile znana jest liczba kolumn. Filtrowanie użytkowników i znaczników można łatwo obsłużyć za pomocą tego podejścia.

Gdy liczba kolumn w kryteriach filtrowania jest arbitralna, ale mała, należy rozważyć użycie różnych zapytań statycznych dla każdej z możliwości.

Tylko wtedy, gdy liczba kolumn w kryteriach filtrowania jest dowolna i potencjalnie duża, jeśli rozważysz użycie zapytań dynamicznych. W takim przypadku ...

Aby być bezpiecznym przed iniekcją SQL, zbuduj lub uzyskaj bibliotekę, która będzie bronić się przed atakiem. Choć trudniejsze, nie jest to niemożliwe. Dotyczy to głównie usuwania ograniczników ciągu SQL w wartościach do filtrowania.

Aby uniknąć ryzykownych zapytań, należy rozważyć użycie widoków specjalnie spreparowanych do tego celu i trochę logiki z przodu, aby ograniczyć sposób wywoływania tych widoków. Jest to najtrudniejsze pod względem czasu i wysiłku programisty.

0

Jeśli korzystasz z Pythona, aby uzyskać dostęp do bazy danych, proponuję użyć Django model system. Istnieje wiele podobnych apisów zarówno dla Pythona, jak i innych języków (szczególnie w rubinach na szynach). Oszczędzam tyle czasu, unikając potrzeby bezpośredniej rozmowy z bazą danych za pomocą SQL.

Od the example link:

#Model definition 
class Blog(models.Model): 
    name = models.CharField(max_length=100) 
    tagline = models.TextField() 

    def __unicode__(self): 
     return self.name 

Wykorzystanie modelu (to skutecznie instrukcja INSERT)

from mysite.blog.models import Blog 
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') 
b.save() 

Zapytania uzyskać znacznie bardziej skomplikowane - można przejść wokół obiektu zapytania i można dodać filtry/sortuj elementy do niego. Kiedy w końcu jesteś gotowy do użycia zapytania, Django tworzy instrukcję SQL, która odzwierciedla wszystkie sposoby dostosowania obiektu zapytania. Myślę, że to jest bardzo słodkie.

Inne zalety tej abstrakcji

  • Twoje modele mogą być tworzone jako tabele bazy danych z kluczy obcych i ograniczeń przez Django
  • wielu baz danych są obsługiwane (PostgreSQL, MySQL, SQL Lite, itp)
  • DJango analizuje twoje szablony i tworzy z nich automatic admin site.
Powiązane problemy