qrzysztof
13.11.2009, 20:17:33
Na stronie użytkownik może wgrywać obrazki z sieci (poprzez podanie adresu url obrazka).
Jak się zabezpieczyć przed wstrzyknięciem wrogiego kodu? Wiadomo, że użytkownik może zmienić rozszerzenie pliku na na przykład .jpg. W ten sposób omija już walidację. Można sprawdzić MIME, tyle że MIME też jest podobno nietrudne do podrobienia.
Zainspirował mnie
ten artykuł. Wynika z niego, że MIME można sfałszować, i że doprowadzić to może do wykonania kodu w IE.
Spawnm
13.11.2009, 20:25:25
Np. zapisuj przez GD robiąc kopie
qrzysztof
13.11.2009, 21:44:51
Co przez to zyskuję?
A jeśli nie robię kopii?
Chodziło mi o to czy jest możliwa taka sytuacja, że z kodu:
<img src="www.obrazki.pl/przyjazny_obrazek.jpg" width="10" height="10" />
zrobi się o wczytaniu obrazka:
<img src="podstawiony_obrazek1.jpg"> <img="podstawiony_obrazek2.jpg" width="10" height="10" />
Nie wiem jak się robi takie ataki. Ale mi się z czymś takim to skojarzyło.
Bo przed podaniem takiego url:
www.obrazki.pl/obrazek.jpg" onload="zlosliwy_kod();
jestem się w stanie zabezpieczyć. Ale jeśli w pliku obrazek.jpg może się kryć skrypt i zostanie on wykonany przy wczytaniu obrazka to nie mam pojęcia jak temu zapobiec.
bolverk
13.11.2009, 21:47:28
Ja w swoim skrypcie walidacji textarea mam mniej więcej tak:
$tag_invalid = array('<script', '</script');
//ochrona przed niodpowiednimi znacznikami
//zmienna $text to łańcuch znaków do walidacji
for($i=0; $i<count($tag_invalid); $i++)
{
if(stristr($text, $tag_invalid[$i])) {
error = "Użyte niedozwolone znaczniki.";
return 0;//bład
}
}
i nie ma problemu ze znacznikami
<script i
</script
qrzysztof
13.11.2009, 22:06:52
Tu jest trochę inna sytuacja.
Z tym co wpisują ludzie w formularzu można sobie poradzić (na przykład tak, jak podałeś).
Problem pojawia się z obrazkiem, którego zawartość jest w 100% pod kontrolą użytkowników. Jego też by trzeba skanować pod kątem znaczników? A może jednak nie ma takiej potrzeby? Z lekką rezerwą podchodzę do tego artykułu z pierwszego posta. A że nie mam wiedzy, jak taki atak mógłby wyglądać (można umieścić w obrazku cokolwiek i zostanie to wykonane? czy może są istotne ograniczenia?) to tym bardziej nie mam pojęcia jak się przed nim zabezpieczyć.
Kolejny
link.
Dobrze, że jest świadomość problemu. Jeszcze rozwiązanie by się przydało.
bolverk
13.11.2009, 22:07:28
Może wtedy otwórz ten plik funkcja fopen() i zbadaj jego zawartosć na niepożadane znaczniki.
//EDIT
Tzn. najpierw sciagnij ten plik na serwer, zbadaj jego zawartosć, wyrzucajac go potem można dać odpowiedni komunikat o błędzie lub zamiescić go bezpiecznie w znaczniku <img>. I ja chyba cos takiego zaimplementuję bo mnie trochę zmartwiłes i zainspirowałes
erix
13.11.2009, 22:25:44
Cytat
Problem pojawia się z obrazkiem, którego zawartość jest w 100% pod kontrolą użytkowników. Jego też by trzeba skanować pod kątem znaczników?
Tak.
A najprościej się od tego uwolnić odpalając któreś narzędzie z pakietu ImageMagick z parametrem
--strip. Wycina on wszystkie metadane i komentarze w pliku graficznym.
Co do praktycznego wykorzystania tego ataku - SimpleMachines Forum było w wersji bodajże 1.1.8 podatne na pobieranie zainfekowanego avatara z zewnątrz. Sprawdzane były tylko uploadowane. Czym to się kończyło? Skrypty stały się botami do rozsyłania spamu. Nieraz do tego stopnia, że load serwera wzrastał do dramatycznych rozmiarów.
qrzysztof
13.11.2009, 23:06:44
Dzięki erix. To dużo wyjaśnia. Nurtuje mnie jeszcze jedna kwestia.
Założenie mam takie, że nie robię kopii na serwerze. W tym momencie musiałbym sprawdzać plik nie tylko przy uploadzie ale przy każdym żądaniu wyświetlenia (ze względu na możliwość podmiany). Ta opcja z oczywistych względów odpada.
Rozsądniejsze rozwiązanie to chyba umieszczenie w bazie oprócz adresu jakiegoś drugiego istotnego atrybutu. Najlepiej jakiejś sumy kontrolnej czy daty modyfikacji. Widzę, że w get_headers na pozycji 4 jest ETag. Jeśli plik będzie podmieniony to będzie on inny i w wyniku porównania z analogiczną pozycją w bazie zostanie zgłoszony błąd. Dzięki temu pliki mogłyby być sprawdzane tylko raz - przy dodawaniu.
Proszę tylko o potwierdzenie jeśli dobrze rozumuję lub o uwagi jeśli nie do końca. To by rozwiązywało mój problem z wgrywaniem obrazków. Przynajmniej na jakiś czas
erix
14.11.2009, 12:01:23
Cytat
Rozsądniejsze rozwiązanie to chyba umieszczenie w bazie oprócz adresu jakiegoś drugiego istotnego atrybutu. Najlepiej jakiejś sumy kontrolnej czy daty modyfikacji.
I po dodaniu obrazka spełniającego warunki, delikwent zmienia plik na zdalnym serwerze. Będziesz każdorazowo pobierał i sprawdzał? Trochę bez sensu.

Lepiej byłoby pobrać do siebie.
qrzysztof
15.11.2009, 01:55:15
Oba rozwiązania mają swoje wady i zalety. Przy "hotlinkowaniu"
-oszczędza się miejsce na dysku,
-oszczędza swój transfer,
-chyba jednak trochę mniej naraża się na ewentualne roszczenia co do praw autorskich, bo pliki nie lądują na serwerze (ale może to tylko mit, w który ja uwierzyłem)
z drugiej strony takie rozwiązanie:
-jest mało bezpieczne (w/w kwestia umieszczania kodu w obrazkach)
-zabezpieczenie się przed takim kodem może być dużo trudniejsze niż przy zapisywaniu kopii u siebie
-jest mało stabilne - obrazek może zostać zmieniony,
-całkiem możliwe, że podbieranie komuś transferu może wywołać większy sprzeciw niż wgranie sobie jego obrazka do siebie (zwłaszcza jeśli dobrze się zabezpieczy w warunkach korzystania z serwisu),
-siłą rzeczy wymaga trochę więcej pracy przy oskryptowaniu, a tak od momentu zapisu na dysku wszystkie obrazki są traktowane jednakowo
Chyba jednak faktycznie szala lekko przechyla się w stronę tworzenia kopii.
A co do Imagicka to teoria teorią a praktyka praktyką niestety. Exec nazwa.pl mi blokuje więc stripa nie zrobię. Z drugiej strony nie wiem czy samo odczytanie przez imagick_readimage() i zapis przez imagick_writeimage() nawet bez zmiany rozdzielczości nie będą równoważne ze stripem. A jeśli nie to zmiana jakiegoś mało widocznego parametru powinna sprawę załatwić.
Hmmm, ale chciałem zrobić limit obrazka 100KB dla dysku i na przykład 300KB dla sieci (korzystając z tego, że to nie moja powierzchnia idzie). Teraz sprawa się skomplikuje - obrazka z sieci nikt sobie nie pomniejszy, a głupio będzie jak połowa będzie za duża. Z drugiej strony jeśli ja zmniejszę obrazek z czyjejś strony (nawet wgrany przez osobę trzecią) to już chyba wtedy ewidentnie podpadam pod jakiś paragraf. W tym układzie zastanawiam się czy w ogóle nie zrezygnować z możliwości dodawania obrazków z sieci. Raz że wszystko przechodzi wtedy przez dysk użytkownika (więc mniejsza szansa ewentualnych roszczeń). A dwa, widzę że mało który serwis daje możliwość wgrywania zdjęć z innych niż własne zasobów.
Blame
15.11.2009, 08:20:51
Według mnie przy limicie który planujesz(100kb) dla każdego obrazka, możliwość wrzucania sobie innych z sieci jest raczej rzeczą zbędną. Jeśli ma to być forum albo jakiś portal gdzie te obrazki to avatary to te 100kb zupełnie wystarczy na świetnej jakości obrazek 100x100 i na dość ładny gif. No i oczywiście takie rozwiązanie jest o niebo prostsze/wygodniejsze.
qrzysztof
15.11.2009, 10:22:10
To nie będą awatary. Strona jest z testami i do pytań można dodawać zdjęcia.
Myślę, że rozmiar mógłbym dać max do 125KB. Nie tyle chodzi mi tu o dostępną powierzchnię na serwerze (bo ta jest więcej niż wystarczająca) co o szybkość ładowania się takiego obrazka potem i transfer z tym związany.
Wszystkie obrazki będą zmniejszane do max rozdzielczości 200x200. Chciałbym mieć te obrazki na serwerze w rozmiarze nie przekraczającym 125KB. Na etapie wgrywania obrazka mogę ewentualnie trochę podnieść limit. Pytanie tylko czy te biblioteki graficzne pozwalają ustalać sobie rozmiar pliku wyjściowego? Wydaje mi się, że jeśli na przykład skonwertuję wszystkie do jpg z rozmiarem 200x200 i jakością 90 to siłą rzeczy żaden nie przekroczy tych 125KB.
------
Powiedzmy, że nawet przy zapisaniu miniaturki 150x150 i wersji większej dostępnej na żądanie np 600x400 przy konwersji tego do jpega w jakości 90 mógłbym sobie spokojnie ustawić limit 0,5MB na taki obrazek a oba wyjściowe prawie na pewno nie przekroczyłyby 125KB. A 0,5MB to już wystarczy do większości obrazków.
Blame
15.11.2009, 19:02:45
Ale zaraz zaraz, po co ta konwersja? po co tyle kombinowania? Ustalasz sobie limit wielkości i rozmiaru obrazka i jeśli jest większy to bardzo mi przykro i tyle. Po co chcesz obciążać serwer czymś co leży w interesie użytkownika i zajmie mu max 30 sekund?
qrzysztof
15.11.2009, 19:19:06
To w przypadku obrazków z sieci tylko. Wtedy dodawanie z sieci miałoby sens bo raz że większość obrazków mieściłaby się w limicie, a na serwerze dużo by nie zajmowały. A tak alternatywa to albo niski limit, albo duże pliki na serwerze. Szczególnie to ostatnie byłoby uciążliwe, bo plik jest wgrywany raz, a wyświetlany wiele razy.
Blame
15.11.2009, 19:45:00
Chodziło mi o to, że to użytkownik powinien się przejmować tym, żeby jego obrazek mieścił się w ustalonych przez ciebie limitach a ty tylko sprawdzasz czy tak jest, jeśli nie to go odrzucasz i wywalasz komunikat. Po co sobie życie komplikować?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.