W mojej aplikacji zaimplementowałem ograniczenie do ataków CSRF zgodnie z informacjami, które przeczytałem na pewnym blogu w Internecie. W szczególności te posty były motorem mojej implementacji
- Najlepsze praktyki dotyczące ASP.NET MVC od zespołu ds. Treści programistów ASP.NET i narzędzi internetowych
- Anatomia ataku typu cross-site Request Forgery Attack z bloga Phila Haacka
- AntiForgeryToken w ASP.NET MVC Framework - Html.AntiForgeryToken i ValidateAntiForgeryToken Atrybut z bloga Davida Haydena
Zasadniczo te artykuły i rekomendacje mówią, że aby zapobiec atakowi CSRF, każdy powinien wdrożyć następujący kod:
1) Dodaj [ValidateAntiForgeryToken]
na każdej akcji, która akceptuje czasownik HTTP POST
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SomeAction( SomeModel model ) {
}
2) Dodaj <%= Html.AntiForgeryToken() %>
pomocnika do formularzy, które przesyłają dane do serwera
<div style="text-align:right; padding: 8px;">
<%= Html.AntiForgeryToken() %>
<input type="submit" id="btnSave" value="Save" />
</div>
W każdym razie w niektórych częściach mojej aplikacji wykonuję testy Ajax POST z jQuery na serwerze, bez żadnej formy. Dzieje się tak na przykład, gdy pozwalam użytkownikowi kliknąć obraz, aby wykonać określoną akcję.
Załóżmy, że mam tabelę z listą działań. Mam obraz w kolumnie tabeli z napisem „Oznacz aktywność jako zakończoną”, a kiedy użytkownik kliknie tę aktywność, wykonuję test POST Ajax, jak w poniższym przykładzie:
$("a.markAsDone").click(function (event) {
event.preventDefault();
$.ajax({
type: "post",
dataType: "html",
url: $(this).attr("rel"),
data: {},
success: function (response) {
// ....
}
});
});
Jak mogę wykorzystać <%= Html.AntiForgeryToken() %>
w tych przypadkach? Czy powinienem dołączyć wywołanie pomocnika do parametru danych wywołania Ajax?
Przepraszamy za długi post i bardzo dziękuję za pomoc
EDYCJA :
Zgodnie z odpowiedzią jayrdub użyłem w następujący sposób
$("a.markAsDone").click(function (event) {
event.preventDefault();
$.ajax({
type: "post",
dataType: "html",
url: $(this).attr("rel"),
data: {
AddAntiForgeryToken({}),
id: parseInt($(this).attr("title"))
},
success: function (response) {
// ....
}
});
});
Odpowiedzi:
Używam prostej funkcji js takiej jak ta
Ponieważ każdy formularz na stronie będzie miał tę samą wartość dla tokena, po prostu umieść coś takiego na najwyższej stronie wzorcowej
Następnie w wywołaniu ajax do (edytowane w celu dopasowania do drugiego przykładu)
źródło
AddAntiForgeryToken
, na przykład:data: AddAntiForgeryToken({ id: parseInt($(this).attr("title")) }),
ajaxSend
lub zastąpienie,ajax
aby zawsze ulepszyćdata
token zapobiegający fałszowaniu? Może dodając trochę czeku, aby upewnić się, żeurl
jest on przeznaczony dla twojego serwera.Podoba mi się rozwiązanie dostarczone przez 360Airwalk, ale można je nieco ulepszyć.
Pierwszy problem polega na tym, że jeśli robisz
$.post()
z pustymi danymi, jQuery nie dodajeContent-Type
nagłówka, aw tym przypadku ASP.NET MVC nie odbiera i nie sprawdza tokena. Musisz więc upewnić się, że nagłówek jest zawsze dostępny.Kolejnym ulepszeniem jest obsługa wszystkich czasowników HTTP z zawartością : POST, PUT, DELETE itp. Chociaż możesz używać tylko POST w swojej aplikacji, lepiej mieć ogólne rozwiązanie i sprawdzić, czy wszystkie dane otrzymane za pomocą dowolnego czasownika są zabezpieczone przed fałszowaniem znak.
źródło
.ajaxSend()
stanów „Począwszy od jQuery 1.8, metoda .ajaxSend () powinna być dołączana tylko do dokumentu”. api.jquery.com/ajaxsendoptions
pochodzi, co jest wymienione w końcowymif
zestawieniu? Dzięki.Wiem, że istnieje wiele innych odpowiedzi, ale ten artykuł jest miły i zwięzły i zmusza cię do sprawdzenia wszystkich swoich HttpPosts, a nie tylko niektórych z nich:
http://richiban.wordpress.com/2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/
Używa nagłówków HTTP zamiast próbować modyfikować kolekcję formularzy.
serwer
Klient
źródło
Czuję się tutaj jak zaawansowany nekromanta, ale nadal jest to problem 4 lata później w MVC5.
Aby poprawnie obsłużyć żądania ajax, token zapobiegający fałszowaniu musi zostać przekazany do serwera podczas wywołań ajax. Zintegrowanie go z danymi i modelami postów jest nieuporządkowane i niepotrzebne. Dodanie tokena jako niestandardowego nagłówka jest czyste i wielokrotnego użytku - i możesz go skonfigurować, abyś nie musiał pamiętać, aby to robić za każdym razem.
Istnieje wyjątek - dyskretne ajax nie wymaga specjalnego traktowania dla wywołań ajax. Token jest przekazywany jak zwykle w zwykłym ukrytym polu wejściowym. Dokładnie tak samo jak zwykły test POST.
_Layout.cshtml
W _layout.cshtml mam ten blok JavaScript. Nie zapisuje tokena w DOM, lecz używa jQuery do wyodrębnienia go z ukrytego literału wejściowego, który generuje MVC Helper. Ciąg Magic, który jest nazwą nagłówka, jest zdefiniowany jako stała w klasie atrybutu.
Zwróć uwagę na użycie pojedynczych cudzysłowów w funkcji beforeSend - renderowany element wejściowy używa podwójnych cudzysłowów, które łamałyby literał JavaScript.
JavaScript klienta
Po wykonaniu tej czynności wywoływana jest powyższa funkcja beforeSend, a AntiForgeryToken jest automatycznie dodawany do nagłówków żądania.
Biblioteka serwerów
Atrybut niestandardowy jest wymagany do przetworzenia niestandardowego tokena. To opiera się na rozwiązaniu @ viggity, ale poprawnie obsługuje dyskretne ajax. Ten kod można schować we wspólnej bibliotece
Serwer / kontroler
Teraz po prostu zastosujesz atrybut do swojej akcji. Jeszcze lepiej możesz zastosować ten atrybut do kontrolera, a wszystkie żądania zostaną zatwierdzone.
źródło
$.ajaxSetup
się zdefiniować ogólnybeforesend
moduł obsługi zdarzeń, może się zdarzyć, że go zastąpisz. Znalazłem inne rozwiązanie, w którym możesz dodać drugi moduł obsługi, który również zostanie wywołany. Działa ładnie i nie psuje twojej implementacji.Nie używaj Html.AntiForgeryToken . Zamiast tego należy użyć funkcji AntiForgery.GetTokens i AntiForgery.Validate z interfejsu API sieci Web, jak opisano w Zapobieganie atakom typu CSRF (Cross-Site Request Forgery) w aplikacji ASP.NET MVC .
źródło
Właśnie wdrażałem ten faktyczny problem w moim obecnym projekcie. Zrobiłem to dla wszystkich ajax-POST, które wymagały uwierzytelnionego użytkownika.
Po pierwsze postanowiłem podciągnąć moje wywołania ajaxowe jquery, więc nie powtarzam się zbyt często. ten fragment kodu javascript zapewnia, że wszystkie wywołania ajax (post) dodadzą do żądania mój token sprawdzania poprawności. Uwaga: nazwa __RequestVerificationToken jest używana przez platformę .Net, dzięki czemu mogę korzystać ze standardowych funkcji Anti-CSRF, jak pokazano poniżej.
W swoich widokach, w których potrzebujesz tokena, aby był dostępny dla powyższego javascript, po prostu użyj wspólnego HTML-Helper. Możesz w zasadzie dodać ten kod, gdziekolwiek chcesz. Umieściłem go w instrukcji if (Request.IsAuthenticated):
W kontrolerze wystarczy użyć standardowego mechanizmu Anti-CSRF ASP.Net MVC. Zrobiłem to w ten sposób (chociaż faktycznie używałem soli).
Za pomocą Firebug lub podobnego narzędzia możesz łatwo zobaczyć, w jaki sposób twoje żądania POST mają teraz dołączony parametr __RequestVerificationToken.
źródło
Myślę, że wszystko, co musisz zrobić, to upewnić się, że dane wejściowe „__RequestVerificationToken” są uwzględnione w żądaniu POST. Druga połowa informacji (tj. Token w pliku cookie użytkownika) jest już wysyłana automatycznie z żądaniem AJAX POST.
Na przykład,
źródło
AntiForgeryToken
to i tak wszystko jest sporne. Jeśli tak (nie jestem pewien, w jaki sposób otrzymujesz taki w takim przypadku, ale zakładając, że tak), powyższe działałoby dobrze. Jeśli próbujesz utworzyć prostą stronę internetową, która opublikuje żądanie na serwerze oczekującym tego tokena, a serwer nie wygenerował tej strony, to nie masz szczęścia. Taki jest właśnie sens AntiForgeryToken ...Możesz to zrobić także:
To używa
Razor
, ale jeśli używaszWebForms
składni, możesz równie dobrze używać<%= %>
znacznikówźródło
Po moim komentarzu do odpowiedzi @ JBall, która pomogła mi po drodze, jest to ostateczna odpowiedź, która działa dla mnie. Korzystam z MVC i Razor i przesyłam formularz za pomocą jQuery AJAX, dzięki czemu mogę zaktualizować widok częściowy z nowymi wynikami i nie chciałem robić pełnego postback (i migotania strony).
Dodaj
@Html.AntiForgeryToken()
wnętrze formularza jak zwykle.Mój kod przycisku przesyłania AJAX (tj. Zdarzenie onclick) to:
Zostawiłem akcję „sukces”, ponieważ pokazuje, w jaki sposób aktualizowany jest widok częściowy, który zawiera siatkę MvcJqGrid i jak jest odświeżany (bardzo wydajna siatka jqGrid i jest to doskonałe opakowanie MVC).
Moja metoda kontrolera wygląda następująco:
Muszę przyznać, że nie jestem fanem POSTingowania danych całego formularza jako modelu, ale jeśli musisz to zrobić, jest to jeden ze sposobów, który działa. MVC po prostu sprawia, że wiązanie danych jest zbyt łatwe, więc zamiast wysyłać 16 pojedynczych wartości (lub słabo wpisanego FormCollection), to chyba OK. Jeśli wiesz lepiej, daj mi znać, ponieważ chcę stworzyć solidny kod MVC C #.
źródło
znalazłem ten bardzo sprytny pomysł z https://gist.github.com/scottrippey/3428114 dla każdego wywołania $ .ajax, modyfikuje żądanie i dodaje token.
źródło
if (options.contentType != false && options.contentType.indexOf('application/json') === 0) {
aby złapać wywołania Ajax, które nie określiły typu zawartości1. Zdefiniuj funkcję, aby pobrać Token z serwera
2. Pobierz token i ustaw nagłówek przed wysłaniem na serwer
3. Sprawdzanie poprawności Onserver na HttpRequestBase dla metody, którą obsługujesz Post / get
źródło
Wiem, że minęło trochę czasu, odkąd to pytanie zostało opublikowane, ale znalazłem naprawdę użyteczny zasób, który omawia użycie AntiForgeryToken i sprawia, że korzystanie z niego jest mniej kłopotliwe. Zapewnia również wtyczkę jquery do łatwego włączania tokenu antygranicznego w połączeniach AJAX:
Przepisy dotyczące wniosków o fałszerstwo dotyczące ASP.NET MVC i AJAX
Nie wnoszę wiele, ale może ktoś uzna to za przydatne.
źródło
źródło
Oto najprostszy sposób, jaki widziałem. Uwaga: Upewnij się, że masz w widoku „@ Html.AntiForgeryToken ()”
źródło
Nieznaczne ulepszenie rozwiązania 360Airwalk. To osadza token Anti Forgery w funkcji javascript, więc @ Html.AntiForgeryToken () nie musi już być dołączany do każdego widoku.
źródło
źródło
Używam wpisu ajax do uruchomienia metody usuwania (zdarza się, że pochodzi z osi czasu Visjs, ale to nie jest relelvant). Oto co ja siostrzyczko:
To jest mój Index.cshtml
Wszystko, co tutaj dodałem, to
@Html.AntiForgeryToken()
aby token pojawił się na stronieNastępnie w moim poście ajax użyłem:
Co dodaje wartość tokena, zeskrobaną ze strony, do opublikowanych pól
Wcześniej próbowałem umieścić wartość w nagłówkach, ale otrzymałem ten sam błąd
Publikuj ulepszenia. To z pewnością wydaje się proste podejście, które mogę zrozumieć
źródło
Dobra, dużo postów tutaj, żaden z nich nie pomógł mi, dni i dni google, i nadal nie doszedłem do tego stopnia, że pisałem całą aplikację od zera, a potem zauważyłem ten mały samorodek na moim Web.confg
Teraz nie wiem, dlaczego go dodałem, ale zauważyłem, że jest ignorowany w trybie debugowania, a nie w trybie produkcyjnym (IE zainstalowany gdzieś w IIS)
Dla mnie rozwiązaniem była jedna z 2 opcji, ponieważ nie pamiętam, dlaczego go dodałem, nie mogę się upewnić, że inne rzeczy nie zależą od tego, a po drugie, nazwa domeny musi być małymi literami, a TLD nie tak jak zrobiłem w * .localLookup.net
Może to pomaga, może nie. Mam nadzieję, że to komuś pomoże
źródło
Znalezione przeze mnie rozwiązanie nie dotyczy ASPX, ale Razor, ale problem, który można całkiem rozwiązać.
Rozwiązałem to, dodając do żądania AntiForgery. Pomocnik HTML nie tworzy identyfikatora HTML z wywołaniem
Aby dodać token do żądania końcowego, właśnie dodałem identyfikator AntiForgery do ukrytego pola za pomocą jquery:
Spowodowało to, że kontroler zaakceptował żądanie z atrybutem [ValidateAntiForgeryToken]
źródło
AntiforgeryToken nadal jest uciążliwy, żaden z powyższych przykładów nie działał dla mnie słowo w słowo. Jest ich tam zbyt wielu. Więc połączyłem je wszystkie. Potrzebujesz @ Html.AntiforgeryToken w formie wiszącej wokół iirc
Rozwiązany tak:
W razie wątpliwości dodaj więcej znaków $
źródło