Do łączenia tabel używam modeli SQL Zend Framework. Jako przykład zmodyfikowałem mój rzeczywisty kod, ale myślę, że zrozumiesz:
$this->getSelect()->join(
array('sections' => $sectionsTableName),
'main_table.banner_id = pages.banner_id',
array()
)
->where("sections.section= '$section' OR sections.section = '0' OR (sections.section = '6' AND ? LIKE main_table.url)",$url)
->group('main_table.banner_id');
Strona jest ładowana za pomocą ajax, a parametr sekcji $ jest wysyłany jako parametr GET ( www.example.com/controllerName/index/display/3?paremeter1=example§ion=www.example2.com
).
Teraz jest problem, jeśli ktoś wykona coś takiego:
www.example.com/controllerName/index/display/3?paremeter1=example&url=(SELECT 3630 FROM(SELECT COUNT(*),CONCAT(0x7170786a71,(SELECT (ELT(3630=3630,1))),0x717a716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)
W ten sposób użytkownik może zrzucić całą bazę danych. Dane nie będą wyświetlane, ale SQL nadal wykona zrzut, który może spowodować przeciążenie sql.
Pytania:
- Jaki jest najlepszy sposób na uniknięcie takiego scenariusza?
- Teraz martwię się o poprzednich klientów. Czy dzięki temu kodowi można wykonać jeszcze więcej działań związanych z ryzykiem, takich jak delate lub alter table? Chyba nie dlatego, że nie można wstawić żadnej innej instrukcji niż SELECT do podselekcji, aby DELETE spowodowało błąd składniowy sql. Czy mam rację?
AKTUALIZACJA: Mój przykład nie jest prawidłową ilustracją wstrzyknięcia SQL, ponieważ istnieje „znak wokół sekcji $ i dlatego nie będzie możliwe wykonanie zastrzyku. W każdym razie byłoby to możliwe, gdy oczekuje się wartości całkowitej i gdy nie filtruje się liczb całkowitych. Zobacz mój komentarz poniżej.
źródło
$db = Mage::getSingleton('core/resource')->getConnection('core_read');
a$db->quote()
nawet w twoim przypadku spójrz na$db->quoteInto
. Jeśli$this
jest zasobem, można zrobić:$this->getConnection('core_read')->quoteInto()
czy jest to zbiór można zrobić:$this->getResource()->getConnection('core_read')->quoteInto()
. wzdłuż tych linii. Jeśli to pomoże ci poprowadzić cię do celu.'
znak przed(
znakiem, a zatem(SELECT
wszystko inne będzie tak samo jak ciąg znaków i nie będzie działać. Gdy pole jest liczbą całkowitą,'
nie jest potrzebne i umożliwia taki scenariusz. Ale liczba całkowita powinna być zawsze filtrowana,intval()
więc nie stanowi to również problemu.'
? Tak' AND (SELECT ...) '
? Nawiasem mówiąc, nie sądzę, że Zend nie cytuje tego ... A jeśli użyjesz powiązań, PDO to załatwi. Po prostu nigdy nie używaj takich"sections.section= '$section'"
Odpowiedzi:
Sprawdź poprawność wprowadzonych danych!
Tak dobrze, jak tylko możesz.
Kilka sugestii dotyczących walidacji:
Sprawdź długość zmiennej otrzymanej za pomocą parametru GET. Nie trzeba akceptować niekończącego się długiego łańcucha.
Sprawdź poprawność nazwy domeny. Jakiego formatu mają oczekiwane nazwy domen? Czy to zawsze www.mydomain.tld? Utwórz wyrażenie regularne, które sprawdza dopasowanie lub (lepiej) użyj
Zend_Validate_Hostname
:Biała lista: Czy wiesz, których nazw domen się spodziewać? Możesz utworzyć listę dozwolonych domen i porównać je. Upuść resztę.
Czarne nazwy domen i / lub znaki: jeśli oczekujesz nazwy domeny, nie musisz akceptować żadnych innych znaków niż az i 0-9 i „.” (chyba że pracujesz ze specjalnymi nazwami domen).
źródło