Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: CSRF
Forum PHP.pl > Forum > PHP
aren
Jak wiemy tagi bbcode etc. np [img] stwarzaja nie male zagrozenie. Jako img moge podstawic plik php i robic co mi sie zywnie podoba (podkrasc cookies, sessje etc.). Chcialbym sie Was polecic jak zapobiec tego typu zagrozeniom? Uzytkownicy maja avatary, wyswietlane na forach, swoich profilach itd. potencjalnie kazdy moglby byc niebezpieczny. Jak wiec zapobiec, czy zablokowac tego typu zagrozenie? Z pewnoscia sprawdzanie czy dany plik graficzny pochodzi z tych bardziej znanych, zaufanych serwisow (np. imagshack itd.) jest jakims rozwiazaniem, ale niewatpliwie uciazliwe dla uzytkownikow, ktorzy nie rzadko wola hostowac pliki u siebie.

Z gory dziekuje za pomoc.
nrm
ja mam sprawdzanie czy to jest obrazek z timeoutem na 2s. Niestety jest to kiepskie rozwiązanie, tymczasówka, która kiedyś przydałoby się zmienic na coś konkretnego więc przypne sie do tematu winksmiley.jpg

ps. kiedyś testowałem chyba z 12 ogólnodostępnych klas do bbcode i wszystkie (exclamation.gif) jak leci nie sprawdzały [img] :/
aren
No wiec wlasnie, wiec jak narazie chyba pozostaje zrobic preg_match...
kubal
nie wiem dokładnie o co wam chodzi (to przez przemęczenie winksmiley.jpg) ale u mnie tag img wygląda tak:
Kod
    // [img]http://www/image.gif[/img]
    $s = preg_replace("/\[img\](http:\/\/[^\s'\"<>]+(\.(jpg|gif|png)))\[\/img\]/i", "<IMG border=\"0\" src=\"\\1\">", $s);

    // [img=http://www/image.gif]
    $s = preg_replace("/\[img=(http:\/\/[^\s'\"<>]+(\.(gif|jpg|png)))\]/i", "<IMG border=\"0\" src=\"\\1\">", $s);

i jest to chyba bezpieczne rozwiązanie...
nrm
o ile jpg jest jpgiem tongue.gif
SirZooro
Wg mnie przed CSRF nie da się zabezpieczyć inaczej niż przez wyłączenie możliwości linkowania obrazków - przecież można podać link do pliku jpg na innym serwerze, ale próba jego pobrania zaowocuje redirectem na właściwy adres. Jeżeli już koniecznie to chcesz mieć, to pozwalaj na linkowanie tylko obrazków z zaufanych serwerów (np. imageshack), ew. przechowuj obrazki u siebie na serwerze. To ostatnie też nie jest jednak za dobre, bo otwiera drogę do przemycenia kodu php na serwer.
nrm
@SirZooro: to żadne wyjście z sytuacji, równie dobrze w ogóle można img nie robić. Userzy wklejają adresy skąd popadnie i wcale 10 najpopularnjieszych hostow nie zalatwilo by nawet polowy wklejanych adresow.
.radex
Wikipedia tyle tylko mówi na ten temat:

Istnieje cały szereg metod, które utrudniają przeprowadzenie skutecznego ataku CSRF.
Hasła jednorazowe uniemożliwiają osobie niepowołanej spreparowanie poprawnego żądania do serwera. Wymóg podania hasła udostępnionego wyłącznie dysponentowi konta na papierowej liście lub tokenie bądź też przesłanego SMSem na numer telefonu komórkowego praktycznie wyklucza powodzenie ataku CSRF. to raczej małej aplikacji nie dotyczy
Im większe konsekwencje dla użytkownika niesie korzystanie ze strony, tym krótszy powinien być okres ważności zalogowania i dopuszczalny czas bezczynności.
Żądania mające skutki uboczne mogą wymagać potwierdzenia, połączonego ew. z ponowną autoryzacją.
Do każdego formularza można dodawać ukryte pole, zawierające liczbę pseudolosową, która musi zostać przekazana wraz z żądaniem wykonania akcji. Ignorowanie żądań, którym brakuje ukrytej wartości bądź gdy nie pokrywa się ona z liczbą zachowaną po stronie serwera, utrudnia spreparowanie ataku.
Zamiast liczby pseudolosowej przesłać można zawartość ciasteczka służącego do uwierzytelnienia i porównać je z wartością przesłaną w nagłówku żądania HTTP oraz tą zapisaną po stronie serwera. Metoda ta opiera swoje bezpieczeństwo na zasadzie same origin policy, która gwarantuje, że wartość ciasteczka dostępna jest jedynie dla skryptów pochodzących z oryginalnej strony. Zwrócić należy jednak uwagę na to, że odpowiednio spreparowany skrypt może zostać umieszczony w serwisie przy pomocy ataku XSS.

Średnio konkretne, ale na pewno przyda się w zabezpieczeniu strony przeciwko atakowi CSRF

EDIT:

@down - Tak, wiem winksmiley.jpg Ale skoro już mówimy o CSRF, to IMHO warto o tym wspomnieć. smile.gif
nrm
@radex_p: ale to akurat nie na temat winksmiley.jpg
Kicok
Cytat(normanos @ 6.08.2008, 21:40:09 ) *
@radex_p: ale to akurat nie na temat winksmiley.jpg


No ale właśnie takie dodatkowe zabezpieczenia przy wykonywaniu "istotnych akcji" (edytowanie, usuwanie czegoś) przez sprawdzanie referera czy też jakieś losowe ciągi w adresie to jedyny rozsądny sposób. Sprawdzanie zdjęć nic nie da.
Można oczywiście utworzyć białą listę domen, z których można wstawiać zdjęcie, a nawet całkowicie zablokować wstawianie zdjęć z zewnątrz. Jest to skuteczna metoda, ale chyba zbyt irytująca, by mogła być stosowana.
bełdzio
najlepiej uploadować pliki na swoj serwer smile.gif
SirZooro
@bełdzio: teoretycznie tak, ale można sobie niechcący przemycić w ten sposób kod php na serwer smile.gif
bełdzio
ale można się przed tym zabezpieczyc smile.gif najblizsza notka na blogu u mnie bedzie na ten temat :-)
aren
Widzę Panowie, że sporo odpowiedzi. Tak jak niektórzy z Was piszą, nie ma sprawnej metody na zabezpieczenie się przed tego typu wykradaniem danych (mowa głównie o plikach graficznych, które nimi do końca nie są). O tzw. 'białej liście' sam pisałem, ale jest to jak sami wiecie nie bardzo user-friendly. Chciałbym się zapytać, jak to się rozwiązuje w większych aplikacjach? Choćby forum IPB, vBulletin i inne? Przecież nie możliwe jest, że nie ma aplikacji zabezpieczonej odpowiednio.
SirZooro
@bełdzio: zatem czekam - ciekaw jestem co napiszesz smile.gif. Dodam tylko że sprawdzenie rozszerzenia + getimagesize() to za mało.
rzymek01
tak jak pisze bełdzio, wysyłanie plików na swój serwer (można się zabezpieczyć przed złośliwym kodem)

lub jak piszesz bezpieczną aplikację typu potwierdzanie akcji, unikalne id w każdym formularzu to niegroźny Ci ten atak tongue.gif
Sh4dow
Takie działania można skutecznie utrudniać. Ale chyba jedynie od strony ustawień serwera.
Pierwszy jaki pamietam to ustawienia sesji najprostrze sprawdzanie referera skad przyszło zapytanie.
session.referer_check
Dodatkowo można wymusić uzywanie sesji tylko dla zapytan http a naprzyklad juz nie dla xmlrequestow z JS
session.cookie_httponly
Oczywiście można jeszcze ustawić domene i katalog oraz ssl'a dla ciastek z sesja.
Jeśli natomiast przy obrazkach, nie zalezy ci na transferze oraz miejscu na dyskach , to mozesz takie obrazki zgrywać do ciebie i od siebie je serwować.
Może pomóc również własny system tworzenia ID sesji na podstawie identyfikacji użytkownika, jego ip przegladarka system, jakies dane z ciastek lub inne indywidualne dane użytkownika.
zimi
Cytat
@bełdzio: zatem czekam - ciekaw jestem co napiszesz . Dodam tylko że sprawdzenie rozszerzenia + getimagesize() to za mało.

ale mime_content_type" title="Zobacz w manualu PHP" target="_manual, tudzież odpowiedni header" title="Zobacz w manualu PHP" target="_manual dopasowany do rozszerzenia jakie zostało podane... powinno wystarczyć...

edit: tak mi sie wydaję
SirZooro
@zimi: no to źle Ci się wydaje smile.gif - kiedyś udało mi się umieścić w pliku jpg kawałek kodu php. Dzięki temu można potem tak zrobić:
  1. <?php
  2. include "obrazek.jpg"
  3. ?>

W rezultacie na stronie pojawi się trochę krzaków z pliku i wynik wykonania kodu php (np. wywołanie phpinfo).
zimi
nie rozumiem jaką to niesie ze sobą ideę...
ja na swoich stronach obrazki wyświetlam a nie includuję...
nie rozumiem w jaki sposób chciałbyś przeprowadzić atak
SirZooro
Żeby to wykorzystać trzeba:
1. Wysłać taki spreparowany plik na serwer
2. Ścieżkę do tego pliku podać do skryptu który includuje plik podany jako parametr i jednocześnie nie waliduje podanej ścieżki.

Czyli to jest odmiana ataku Local File Inclusion.
zimi
o ho ho ho...
i co jeszcze byś chciał smile.gif hasło bazy danych smile.gif
nie mając tamtej dziury nic z tym nie zrobisz..., przynajmniej ja nie mam pomysłu...

zasadniczo odnoszę wrażenie że to trochę inna ranga CSRF a błędy z include smile.gif
jak ktoś się zastanawia nad pierwszym a ma błędy z drugim to trochę nieporozumienie smile.gif
SirZooro
Zawsze można poszukać smile.gif

Mi chodziło tutaj o pokazanie potencjalnego wektora ataku, a nie wskazywanie że skrypt X można zaatakować w taki czy inny sposób.
.radex
Mogę się mylić, bo nie jestem specem od zabezpieczeń, ale jakoś wydaje mi się taki atak z obrazków na własnym serwerze mało prawdopodobny (chyba, że ktoś ma na prawdę dziurawy skrypt). Domyślam się, że atak CSRF z obrazków działa tak: ktoś przesyła plik php o rozszerzeniu powiedzmy jpg na swój serwer, a na swoim serwerze ma ustawioną specjalną opcję - pliki jpg są traktowane jak php i wykonywane przez parser. Trzymając obrazki użytkowników na serwerze serwisu taki atak jest niemożliwy, ponieważ dla serwera serwisu plik jpg nie jest możliwy do wykonania przez interpreter php. Jedyna możliwość to podmiana .htaccess przez atakującego, lub inne dziury w skrypcie.
WebCM
Szukam uniwersalnego sposobu ochrony przed CSRF. Jeśli wszystkie akcje typu: dodaj, usuń, edytuj, głosuj, kupuj... są wywoływane metodą POST, część problemów jest rozwiązana, np. z obrazkiem na forum prowadzącym do: kuptowar.php?id=123 - ale to nie wszystko. Atakujący może przygotować złośliwą stronę, na której nieświadomie kupimy towar lub usuniemy komentarz.

REFERER
Sprawdzanie strony odsyłającej częściowo zabezpiecza skrypt, lecz niezupełnie. Podobno można zmienić nagłówek za pomocą AJAX lub utworzyć pływającą ramkę (najpierw otworzyć stronę główną serwisu, dodać do niej formularz za pomocą DOM i wysłać). Czy przeglądarki chronią użytkowników przed takimi praktykami?

TAJNY IDENTYFIKATOR
Przed wykonaniem akcji zapisujemy do sesji tajny identyfikator (token), a potem porównujemy go. Nie jestem pewny, czy takie zabezpieczenie jest dobre w przypadku złośliwej pływającej ramki (j.w.). Aby skutecznie ochronić się przed wykonaniem jakiejkolwiek akcji nieświadomie, musielibyśmy tworzyć token dla każdego <form> / żądania AJAX / itd.

Może znacie inne skuteczne metody?

Aha, czy jest sens sprawdzać centralnie referer przy każdym żądaniu POST?
Kod
if($_POST)
{
    if(isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'],$_SERVER['HTTP_HOST'])===false) exit;
}
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.
Invision Power Board © 2001-2025 Invision Power Services, Inc.