Keresztoldalas kéréshamisítás (XSRF/CSRF) támadások megakadályozása az ASP.NET Core-ban
A webhelyek közötti kéréshamisítás a webalkalmazások elleni támadás, amely során egy rosszindulatú webalkalmazás befolyásolhatja az ügyfélböngésző és a böngésző által megbízhatónak hitt webalkalmazás közötti interakciót. Ezek a támadások azért lehetségesek, mert a webböngészők minden kéréssel automatikusan küldenek bizonyos hitelesítési jogkivonatokat egy webhelyre. Ezt a biztonsági rést egykattintásos támadásnak is nevezik, vagy munkamenet-eltérítésnek, mert kihasználja a felhasználó korábban hitelesített munkamenetét. A helyek közötti kérelemhamisítást XSRF-nek vagy CSRF-nek is nevezik.
Példa CSRF-támadásra:
A felhasználó űrlap-hitelesítéssel jelentkezik be
www.good-banking-site.example.com
. A kiszolgáló hitelesíti a felhasználót, és egy hitelesítési cookietartalmazó választ ad ki. A webhely sebezhető a támadásokkal szemben, mert megbízik minden olyan kérésben, amelyet érvényes hitelesítési cookiekap.A felhasználó meglátogat egy rosszindulatú webhelyet,
www.bad-crook-site.example.com
.A kártékony webhely (
www.bad-crook-site.example.com
) az alábbi példához hasonló HTML-űrlapot tartalmaz:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>
Figyelje meg, hogy az űrlap
action
a sebezhető webhelyre, nem pedig a rosszindulatú webhelyre. Ez a CSRF "keresztoldali" része.A felhasználó kiválasztja a Küldés gombot. A böngésző a kérést végrehajtja, és automatikusan tartalmazza a cookie hitelesítést a kért tartományhoz,
www.good-banking-site.example.com
.A kérés a
www.good-banking-site.example.com
kiszolgálón fut a felhasználó hitelesítési környezetével, és bármilyen műveletet végrehajthat, amelyet egy hitelesített felhasználó végrehajthat.
Azon forgatókönyv mellett, amikor a felhasználó kiválasztja az űrlap elküldéséhez a gombot, a rosszindulatú webhely a következőt teheti:
- Futtasson egy szkriptet, amely automatikusan elküldi az űrlapot.
- Küldje el az űrlap beküldését AJAX-kérelemként.
- Rejtse el az űrlapot a CSS használatával.
Ezek az alternatív forgatókönyvek nem igényelnek semmilyen műveletet vagy bemenetet a felhasználótól, kivéve, ha eredetileg meglátogatják a rosszindulatú webhelyet.
A HTTPS használata nem akadályozza meg a CSRF-támadást. A rosszindulatú webhely épp olyan könnyen küldhet https://www.good-banking-site.example.com/
kérést, mint ahogy nem biztonságos kérést küld.
Egyes támadások a GET-kérelmekre reagáló végpontokat támadják meg, ebben az esetben egy képcímke használható a művelet végrehajtásához. Ez a támadási forma gyakori a fórumwebhelyeken, amelyek lehetővé teszik a képeket, de letiltják a JavaScriptet. A GET-kérések állapotát módosító alkalmazások, amelyek változókat vagy erőforrásokat módosítanak, sebezhetők a rosszindulatú támadásokkal szemben. Az állapotot módosító GET-kérelmek nem biztonságosak. Ajánlott eljárás, hogy soha ne változtassunk állapotot GET-kérés során.
A CSRF-támadások a hitelesítéshez cookie-kat használó webalkalmazások ellen lehetségesek, mert:
- A böngészők egy webalkalmazás által kibocsátott cookie-kat tárolnak.
- A tárolt cookie-k munkamenet-cookie-kat tartalmaznak a hitelesített felhasználók számára.
- A böngészők minden, tartományhoz társított cookie-t elküldenek a webalkalmazásnak, függetlenül attól, hogy az alkalmazáskérés hogyan jött létre a böngészőben.
A CSRF-támadások azonban nem korlátozódnak a cookie-k kihasználására. Az alapszintű és a kivonatoló hitelesítés például sebezhető. Miután egy felhasználó bejelentkezett alapszintű vagy kivonatoló hitelesítéssel, a böngésző automatikusan elküldi a hitelesítő adatokat, amíg a munkamenet véget nem ér.
Ebben az összefüggésben munkamenet arra az ügyféloldali munkamenetre vonatkozik, amely során a felhasználó hitelesítése megtörtént. Nem kapcsolódik kiszolgálóoldali munkamenetekhez vagy ASP.NET Core Session Middleware.
A felhasználók óvintézkedéseket tehetnek a CSRF biztonsági rései ellen:
- Kijelentkezés a webalkalmazásból, ha befejezte a használatukat.
- A böngésző cookie-inak rendszeres törlése.
A CSRF biztonsági rései azonban alapvetően a webalkalmazással, nem pedig a végfelhasználóval kapcsolatos problémák.
A hitelesítés alapjai
Cookie-alapú hitelesítés a hitelesítés népszerű formája. A token alapú hitelesítési rendszerek egyre népszerűbbek, különösen az egyoldalas alkalmazások (SPA-k) esetében.
Cookie-alapú hitelesítés
Amikor egy felhasználó a felhasználónevével és jelszavával hitelesít, egy hitelesítési jegyet tartalmazó jogkivonatot kap. A token használható hitelesítéshez és engedélyezéshez. A tokent egy cookie-ként tárolják, amelyet minden kérésnél az ügyféllel együtt küldenek. A cookie létrehozása és érvényesítése a Cookie Hitelesítési köztes szoftverrel történik. A köztes szoftver egy felhasználónevet titkosított cookieszerializál. A következő kérések során a köztes szoftver ellenőrzi a cookie-t, újra létrehozza a főkomponenst, és hozzárendeli a főkomponenst a HttpContext.User tulajdonsághoz.
Tokenalapú hitelesítés
Ha egy felhasználó hitelesítése megtörtént, a rendszer tokent ad ki (nem pedig antiforgery tokent). A jogkivonat felhasználói adatokat tartalmaz jogcímek formájában, vagy egy hivatkozási jogkivonat formájában, amely az alkalmazást az alkalmazásban fenntartott felhasználói állapotra mutatja. Amikor egy felhasználó megpróbál hozzáférni egy hitelesítést igénylő erőforráshoz, a rendszer a jogkivonatot egy további engedélyezési fejléccel továbbítja az alkalmazásnak tulajdonosi jogkivonat formájában. Ez a megközelítés állapot nélkülivé teszi az alkalmazást. Minden további kérésben a jogkivonat továbbításra kerül a kiszolgálóoldali érvényesítéshez. Ez a jogkivonat nem titkosított; kódolt. A kiszolgálón a rendszer dekódolja a jogkivonatot, hogy hozzáférjen az adataihoz. A jogkivonat későbbi kérésekre való elküldéséhez tárolja a jogkivonatot a böngésző helyi tárolójában. Ha a jogkivonatot a böngésző helyi tárolójában helyezi el, lekérte és tulajdonosi jogkivonatként használja, védelmet nyújt a CSRF-támadások ellen. Ha azonban az alkalmazás sebezhető az XSS-en vagy egy feltört külső JavaScript-fájlon keresztüli szkriptinjektálással szemben, a kiberbűnözők bármilyen értéket lekérhetnek a helyi tárolóból, és elküldhetik őket maguknak. ASP.NET Core alapértelmezés szerint a változók összes kiszolgálóoldali kimenetét kódolja, így csökkenti az XSS kockázatát. Ha ezt a viselkedést Html.Raw vagy nem megbízható bemenettel rendelkező egyéni kóddal bírálja felül, akkor növelheti az XSS kockázatát.
Ne aggódjon a CSRF biztonsági rése miatt, ha a jogkivonat a böngésző helyi tárolójában van tárolva. A CSRF aggodalomra ad okot, ha a tokent egy cookie-ban tárolják. További információért lásd a GitHub probléma oldalt: az SPA kódminta két cookie-t ad hozzá.
Több, egy tartományban üzemeltetett alkalmazás
A megosztott üzemeltetési környezetek ki vannak téve a munkamenet-eltérítésnek, a bejelentkezési CSRF-nek és más támadásoknak.
Bár example1.contoso.net
és example2.contoso.net
különböző gazdagépek, implicit megbízhatósági kapcsolat áll fenn a *.contoso.net
tartománybeli gazdagépek között. Ez az implicit megbízhatósági kapcsolat lehetővé teszi, hogy a potenciálisan nem megbízható gazdagépek befolyásolják egymás cookie-jait (az AJAX-kéréseket szabályozó azonos eredetű szabályzatok nem feltétlenül vonatkoznak a HTTP-cookie-kra).
Az ugyanazon a tartományon üzemeltetett alkalmazások közötti megbízható cookie-kat kihasználó támadások megelőzhetők, ha nem osztanak meg tartományokat. Ha az egyes alkalmazásokat a saját tartományában üzemeltetik, nincs kihasználandó implicit cookie megbízhatósági kapcsolat.
Antiforgery az ASP.NET Core-ban
Figyelmeztetés
ASP.NET Core a ASP.NET Core Data Protectionhasználatával implementálja a hamisítás elleni védelmet. Az adatvédelmi vermet úgy kell konfigurálni, hogy egy kiszolgálófarmban működjön. További információért lásd: Az adatvédelem konfigurálása.
Antiforgery middleware kerül be a függőség-injektálási tárolóba, ha az alábbi API-k egyikét meghívják Program.cs
:
További információ: Antiforgery minimális API-kkal.
A FormTagHelper hamisításgátló tokeneket injektál a HTML-űrlapelemekbe. Egy Razor fájlban a következő korrektúra automatikusan létrehozza az antiforgery tokeneket:
<form method="post">
<!-- ... -->
</form>
Hasonlóképpen, IHtmlHelper.BeginForm alapértelmezés szerint antiforgery tokeneket hoz létre, ha az űrlap metódusa nem GET.
A HTML-űrlapelemek antiforgery tokenjeinek automatikus létrehozása akkor történik, ha a <form>
címke tartalmazza a method="post"
attribútumot, és az alábbiak bármelyike igaz:
- A műveletattribútum üres (
action=""
). - A műveletattribútum nincs megadva (
<form method="post">
).
A HTML-űrlapelemekhez tartozó antiforgery tokenek automatikus létrehozása letiltható:
Explicit módon tiltsa le az antiforgery tokeneket a
asp-antiforgery
attribútummal:<form method="post" asp-antiforgery="false"> <!-- ... --> </form>
Az űrlapelem ki van zárva a Címkesegítők közül a Tag Helper ! opt-out szimbólumokhasználatával.
<!form method="post"> <!-- ... --> </!form>
Távolítsa el a
FormTagHelper
a nézetből. AFormTagHelper
eltávolítható egy nézetből az alábbi irányelv Razor nézethez való hozzáadásával:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Jegyzet
Razor lapok automatikusan védettek az XSRF/CSRF támadások ellen. További információ: XSRF/CSRF és Razor Pages.
A CSRF-támadások elleni védelem leggyakoribb módja a szinkronizáló jogkivonat-minta (STP) használata. Az STP akkor használatos, ha a felhasználó űrlapadatokat tartalmazó lapot kér:
- A kiszolgáló egy, az aktuális felhasználó identitásához társított jogkivonatot küld a kliensnek.
- Az ügyfél visszaküldi a jogkivonatot a kiszolgálónak ellenőrzés céljából.
- Ha a kiszolgáló olyan jogkivonatot kap, amely nem egyezik a hitelesített felhasználó identitásával, a rendszer elutasítja a kérést.
A token egyedi és kiszámíthatatlan. A jogkivonat arra is használható, hogy biztosítsa a kérelmek sorozatának megfelelő sorrendjét (például a következő kérelmek sorrendjének biztosításához: 1. oldal > 2. oldal > 3. oldal). Az összes ASP.NET Core MVC és Razor Pages sablonú űrlap valahogy antiforgery tokeneket hoz létre. A következő példanézet-páros antiforgery biztonsági tokeneket hoz létre:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
Kifejezetten adjon hozzá egy hamisítás elleni tokent egy <form>
elemhez a Tag Helper és a HTML-segéd használata nélkül @Html.AntiForgeryToken
.
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Az előző esetekben ASP.NET Core az alábbi példához hasonló rejtett űrlapmezőt ad hozzá:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core három szűrőt tartalmaz, az antiforgery tokenek használatát:
Hamisításvédelem AddControllers
A AddControllers hívása nem engedélyezni az antiforgery tokeneket. A AddControllersWithViews-t meg kell hívni, hogy beépített hamisításgátló token-támogatással rendelkezzen.
Több böngészőlap és a szinkronizáló token sablon
Nem támogatott a több fül, amelyben különböző felhasználókként, vagy az egyik fülben névtelenként van bejelentkezve.
Antiforgery konfigurálása AntiforgeryOptions
AntiforgeryOptions testreszabása a Program.cs
-en:
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Állítsa be az antiforgery Cookie
tulajdonságokat a CookieBuilder osztály tulajdonságaival, ahogyan az az alábbi táblázatban látható.
Opció | Leírás |
---|---|
Cookie | Meghatározza az antiforgery cookie-k létrehozásához használt beállításokat. |
FormFieldName | Annak a rejtett űrlapmezőnek a neve, amelyet az antiforgery rendszer használ az antiforgery tokenek nézetekben való megjelenítéséhez. |
HeaderName | Az antiforgery rendszer által használt fejléc neve. Ha null , a rendszer csak az űrlapadatokat veszi figyelembe. |
SuppressXFrameOptionsHeader | Megadja, hogy el kívánja-e tiltani a X-Frame-Options fejléc generálását. Alapértelmezés szerint a fejléc "SAMEORIGIN" értékkel jön létre. Alapértelmezés szerint false . |
További információ: CookieAuthenticationOptions.
Antiforgery tokenek létrehozása IAntiforgery
IAntiforgery biztosítja az API-t az antiforgery funkciók konfigurálásához.
IAntiforgery
a Program.cs
használatával kérhető meg WebApplication.Services-ben. Az alábbi példa az alkalmazás kezdőlapján használt köztes szoftvert használja egy antiforgery token létrehozásához, és cookie-ként küldi el a válaszban.
app.UseRouting();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
}
return next(context);
});
Az előző példa egy cookie nevű XSRF-TOKEN
-et állít be. Az ügyfél elolvashatja ezt a cookie, és az AJAX-kérelmekhez csatolt fejlécként megadhatja az értékét. Az Angular például beépített XSRF-védelmet tartalmaz, amely alapértelmezés szerint egy cookie nevű XSRF-TOKEN
-t olvas be.
Hamisítás elleni ellenőrzés megkövetelése
Az ValidateAntiForgeryToken műveletszűrő egyéni műveletekre, vezérlőkre vagy globálisan alkalmazható. A szűrőt alkalmazó műveletekre irányuló kérések le lesznek tiltva, kivéve, ha a kérés érvényes antiforgery-jogkivonatot tartalmaz:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
A ValidateAntiForgeryToken
attribútumhoz jogkivonatra van szükség az általa jelölt műveleti módszerekre irányuló kérelmekhez, beleértve a HTTP GET-kérelmeket is. Ha az alkalmazás vezérlőire a ValidateAntiForgeryToken
attribútum van alkalmazva, akkor a IgnoreAntiforgeryToken
attribútummal felülírható.
Az antiforgery tokenek automatikus ellenőrzése csak a nem biztonságos HTTP-metódusok esetén történik meg.
Ahelyett, hogy a ValidateAntiForgeryToken
attribútumot általánosan alkalmazná, majd felülírná IgnoreAntiforgeryToken
attribútumokkal, az AutoValidateAntiforgeryToken attribútum használható. Ez az attribútum ugyanúgy működik, mint a ValidateAntiForgeryToken
attribútum, azzal a különbségkel, hogy nem igényel jogkivonatokat a következő HTTP-metódusokkal végrehajtott kérelmekhez:
- SZEREZZ
- FEJ
- OPCIÓK
- NYOM
Javasoljuk a AutoValidateAntiforgeryToken
széles körű használatát nem API-szcenáriókhoz. Ez az attribútum biztosítja, hogy a POST-műveletek alapértelmezés szerint védettek legyenek. A másik lehetőség az, hogy alapértelmezés szerint figyelmen kívül hagyja az antiforgery tokeneket, kivéve, ha ValidateAntiForgeryToken
az egyes műveleti módszerekre van alkalmazva. Ebben a forgatókönyvben valószínűbb, hogy egy POST-műveletmetódus véletlenül védtelen marad, így az alkalmazás sebezhető lesz a CSRF-támadásokkal szemben. Minden POST-nak el kell küldenie a hamisítás elleni tokent.
Az API-k nem rendelkeznek automatikus mechanizmusokkal a jogkivonat nemcookie részének küldéséhez. A megvalósítás valószínűleg az ügyfélkód implementálásától függ. Néhány példa alább látható:
Osztályszintű példa:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Globális példa:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Globális vagy vezérlő antiforgery attribútumok felülbírálása
Az IgnoreAntiforgeryToken szűrővel kiküszöbölhető az adott művelethez (vagy vezérlőhöz) tartozó antiforgery token szükségessége. Alkalmazásakor ez a szűrő felülbírálja a magasabb szinten (globálisan vagy vezérlőn) megadott ValidateAntiForgeryToken
és AutoValidateAntiforgeryToken
szűrőket.
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Jogkivonatok frissítése a hitelesítés után
A tokeneket a felhasználó hitelesítése után frissíteni kell úgy, hogy a felhasználót átirányítja egy felületre vagy Razor Pages oldalra.
JavaScript, AJAX és SLA-k
Hagyományos HTML-alapú alkalmazásokban rejtett űrlapmezőkön keresztül továbbítják az antiforgery jogkivonatokat a kiszolgálónak. A modern JavaScript-alapú alkalmazásokban és SLA-kban számos kérés programozott módon történik. Ezek az AJAX-kérések más technikákat, például kérésfejléceket vagy cookie-kat is használhatnak a jogkivonat elküldéséhez.
Ha a cookie-kat hitelesítési jogkivonatok tárolására és API-kérések hitelesítésére használják a kiszolgálón, a CSRF potenciális probléma. Ha a helyi tárolót a jogkivonat tárolására használják, a CSRF biztonsági rése csökkenthető, mivel a rendszer nem küldi el automatikusan a helyi tárolóból származó értékeket a kiszolgálónak minden kéréssel együtt. A helyi tároló használata az antiforgery token ügyfélen való tárolására és a token kérésfejlécben történő elküldésére ajánlott módszer.
Blazor
További információért lásd: ASP.NET Core Blazor hitelesítés és engedélyezés.
JavaScript
JavaScript nézetek használata esetén az azonosító egy szolgáltatás segítségével hozható létre a nézeten belül. Injektálja a IAntiforgery szolgáltatást a nézetbe, és hívja meg GetAndStoreTokens:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
@{
ViewData["Title"] = "JavaScript";
var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
<input id="RequestVerificationToken" type="hidden" value="@requestToken" />
<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", () => {
const resultElement = document.getElementById("result");
document.getElementById("button").addEventListener("click", async () => {
const response = await fetch("@Url.Action("FetchEndpoint")", {
method: "POST",
headers: {
RequestVerificationToken:
document.getElementById("RequestVerificationToken").value
}
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
});
});
</script>
}
Az előző példa JavaScript használatával olvassa be az AJAX POST fejléc rejtett mezőértékét.
Ez a megközelítés szükségtelenné teszi a cookie-k szerverről történő közvetlen beállítását vagy kliensről való közvetlen olvasását. Amikor azonban a IAntiforgery szolgáltatás injektálása nem lehetséges, használja a JavaScriptet a jogkivonatok eléréséhez a cookie-kban.
- Hozzáférési jogkivonatok a kiszolgálóra irányuló további kérésekben, általában
same-origin
. - A cookietartalmát felhasználva hozzon létre egy fejlécet a token értékével.
Feltéve, hogy a szkript egy X-XSRF-TOKEN
nevű kérelemfejlécben küldi el a jogkivonatot, konfigurálja az antiforgery szolgáltatást a X-XSRF-TOKEN
fejléc keresésére:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Az alábbi példa hozzáad egy védett végpontot, amely a kérés jogkivonatát egy JavaScript által olvasható cookie-ba írja.
app.UseAuthorization();
app.MapGet("antiforgery/token", (IAntiforgery forgeryService, HttpContext context) =>
{
var tokens = forgeryService.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.Ok();
}).RequireAuthorization();
Az alábbi példa JavaScript használatával küld egy AJAX-kérést a token megszerzésére, és egy másik kérést a megfelelő fejléc alkalmazásával.
var response = await fetch("/antiforgery/token", {
method: "GET",
headers: { "Authorization": authorizationToken }
});
if (response.ok) {
// https://developer.mozilla.org/docs/web/api/document/cookie
const xsrfToken = document.cookie
.split("; ")
.find(row => row.startsWith("XSRF-TOKEN="))
.split("=")[1];
response = await fetch("/JavaScript/FetchEndpoint", {
method: "POST",
headers: { "X-XSRF-TOKEN": xsrfToken, "Authorization": authorizationToken }
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
Jegyzet
Ha az antiforgery token mind a kérelem fejlécben, mind az űrlap hasznos adataiban szerepel, csak a fejlécben lévő token kerül érvényesítésre.
Az API-k minimálisra csökkentésével történő csalás elleni védelem
Hívja a AddAntiforgery és UseAntiforgery(IApplicationBuilder) elemeket az antiforgery szolgáltatások regisztrálására a DI-ben. Az antiforgery tokenek helyek közötti hamisítási támadásokmérséklésére szolgálnak.
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.UseAntiforgery();
app.MapGet("/", () => "Hello World!");
app.Run();
Az hamisításgátló köztesréteg:
- Nem szakítja meg a kérelemfolyamat végrehajtását.
- Beállítja az IAntiforgeryValidationFeature értékét az aktuális kérés HttpContext.Features objektumában.
Az antiforgery token csak akkor érvényes, ha:
- A végpont olyan metaadatokat tartalmaz, amelyek implementálják az IAntiforgeryMetadata, ahol
RequiresValidation=true
. - A végponthoz társított HTTP-metódus egy releváns HTTP-metódus. A vonatkozó metódusok mind HTTP-metódusok, kivéve a TRACE, a OPTIONS, a HEAD és a GET metódusokat.
- A kérés egy érvényes végponthoz van társítva.
Megjegyzés: Ha manuálisan van engedélyezve, az antiforgery köztes szoftvernek a hitelesítés és az engedélyezési köztes szoftver után kell futnia, hogy megakadályozza az űrlapadatok olvasását, ha a felhasználó nincs hitelesítve.
Az űrlapadatokat elfogadó minimális API-k alapértelmezés szerint hamisítás elleni token ellenőrzést igényelnek.
Fontolja meg a következő GenerateForm
metódust:
public static string GenerateForm(string action,
AntiforgeryTokenSet token, bool UseToken=true)
{
string tokenInput = "";
if (UseToken)
{
tokenInput = $@"<input name=""{token.FormFieldName}""
type=""hidden"" value=""{token.RequestToken}"" />";
}
return $@"
<html><body>
<form action=""{action}"" method=""POST"" enctype=""multipart/form-data"">
{tokenInput}
<input type=""text"" name=""name"" />
<input type=""date"" name=""dueDate"" />
<input type=""checkbox"" name=""isCompleted"" />
<input type=""submit"" />
</form>
</body></html>
";
}
Az előző kód három argumentuma a művelet, az antiforgery token, és egy bool
, amely jelzi, hogy a tokent használni kell-e.
Vegye figyelembe a következő mintát:
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.UseAntiforgery();
// Pass token
app.MapGet("/", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.GenerateForm("/todo", token), "text/html");
});
// Don't pass a token, fails
app.MapGet("/SkipToken", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.GenerateForm("/todo",token, false ), "text/html");
});
// Post to /todo2. DisableAntiforgery on that endpoint so no token needed.
app.MapGet("/DisableAntiforgery", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.GenerateForm("/todo2", token, false), "text/html");
});
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
app.Run();
class Todo
{
public required string Name { get; set; }
public bool IsCompleted { get; set; }
public DateTime DueDate { get; set; }
}
public static class MyHtml
{
public static string GenerateForm(string action,
AntiforgeryTokenSet token, bool UseToken=true)
{
string tokenInput = "";
if (UseToken)
{
tokenInput = $@"<input name=""{token.FormFieldName}""
type=""hidden"" value=""{token.RequestToken}"" />";
}
return $@"
<html><body>
<form action=""{action}"" method=""POST"" enctype=""multipart/form-data"">
{tokenInput}
<input type=""text"" name=""name"" />
<input type=""date"" name=""dueDate"" />
<input type=""checkbox"" name=""isCompleted"" />
<input type=""submit"" />
</form>
</body></html>
";
}
}
Az előző kódban a következő bejegyzéseket írja be:
-
/todo
érvényes hamisítás elleni token szükséges. -
/todo2
nem érvényes antiforgery tokent igényelnek, mertDisableAntiforgery
van meghívva.
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
POST küldés címe:
-
/todo
a/
végpont által létrehozott űrlapból sikeres lesz, mert az antiforgery token érvényes. -
/todo
a/SkipToken
által létrehozott űrlapon nem működik, mert a hamisítás elleni védelem nem szerepel. -
/todo2
a/DisableAntiforgery
végpont által létrehozott űrlapból sikeres lesz, mert nincs szükség antiforgery-ra.
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
Ha egy űrlapot hamisítás elleni token nélkül küldenek el:
- A fejlesztési környezetben kivétel történik.
- Az éles környezetben a rendszer naplózza az üzenetet.
Windows-hitelesítés és hamisítást gátló sütik
A Windows-hitelesítés használatakor az alkalmazásvégpontokat ugyanúgy kell védeni a CSRF-támadások ellen, mint a cookie-k esetében. A böngésző implicit módon elküldi a hitelesítési környezetet a kiszolgálónak, és a végpontokat védeni kell a CSRF-támadások ellen.
Antiforgery kiterjesztése
A IAntiforgeryAdditionalDataProvider típus lehetővé teszi a fejlesztők számára a CSRF-ellenes rendszer viselkedésének kiterjesztését az egyes tokenekben történő további adatcserével. A GetAdditionalData metódust minden alkalommal meghívják, amikor létrehoz egy mezőt, és a visszatérési érték a létrehozott mezőben van beágyazva. A megvalósító visszaadhat egy időbélyeget, egy egyedi azonosítót vagy bármilyen más értéket, majd meghívhatja a ValidateAdditionalData függvényt, amikor a jogkivonat érvényesítésre kerül, hogy érvényesítse ezeket az adatokat. Az ügyfél felhasználóneve már be van ágyazva a létrehozott tokenekbe, így nincs szükség ezen információk külön feltüntetésére. Ha egy token kiegészítő adatokat tartalmaz, de nincs konfigurálva IAntiForgeryAdditionalDataProvider
, akkor a kiegészítő adatokat nem érvényesítik.
További erőforrások
A webhelyek közötti kérelemhamisítás (más néven XSRF vagy CSRF) a webalkalmazások elleni támadás, amelynek során egy rosszindulatú webalkalmazás befolyásolhatja az ügyfélböngésző és az a böngésző által megbízhatónak tartott webalkalmazás közötti interakciót. Ezek a támadások azért lehetségesek, mert a webböngészők minden kéréssel automatikusan küldenek bizonyos hitelesítési jogkivonatokat egy webhelyre. Ezt a biztonsági rést egykattintásos támadásnak is nevezik, vagy munkamenet-eltérítésnek, mert kihasználja a felhasználó korábban hitelesített munkamenetét.
Példa CSRF-támadásra:
A felhasználó űrlap-hitelesítéssel jelentkezik be
www.good-banking-site.example.com
. A kiszolgáló hitelesíti a felhasználót, és egy hitelesítési cookietartalmazó választ ad ki. A webhely sebezhető a támadásokkal szemben, mert megbízik minden olyan kérésben, amelyet érvényes hitelesítési cookiekap.A felhasználó meglátogat egy rosszindulatú webhelyet,
www.bad-crook-site.example.com
.A kártékony webhely (
www.bad-crook-site.example.com
) az alábbi példához hasonló HTML-űrlapot tartalmaz:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>
Figyelje meg, hogy az űrlap
action
a sebezhető webhelyre, nem pedig a rosszindulatú webhelyre. Ez a CSRF "keresztoldali" része.A felhasználó kiválasztja a Küldés gombot. A böngésző a kérést végrehajtja, és automatikusan tartalmazza a cookie hitelesítést a kért tartományhoz,
www.good-banking-site.example.com
.A kérés a
www.good-banking-site.example.com
kiszolgálón fut a felhasználó hitelesítési környezetével, és bármilyen műveletet végrehajthat, amelyet egy hitelesített felhasználó végrehajthat.
Azon forgatókönyv mellett, amikor a felhasználó kiválasztja az űrlap elküldéséhez a gombot, a rosszindulatú webhely a következőt teheti:
- Futtasson egy szkriptet, amely automatikusan elküldi az űrlapot.
- Küldje el az űrlap beküldését AJAX-kérelemként.
- Rejtse el az űrlapot a CSS használatával.
Ezek az alternatív forgatókönyvek nem igényelnek semmilyen műveletet vagy bemenetet a felhasználótól, kivéve, ha eredetileg meglátogatják a rosszindulatú webhelyet.
A HTTPS használata nem akadályozza meg a CSRF-támadást. A rosszindulatú webhely éppoly könnyen küldhet https://www.good-banking-site.example.com/
kérést, mint egy nem biztonságosat.
Egyes támadások a GET-kérelmekre reagáló végpontokat támadják meg, ebben az esetben egy képcímke használható a művelet végrehajtásához. Ez a támadási forma gyakori a fórumwebhelyeken, amelyek lehetővé teszik a képeket, de letiltják a JavaScriptet. A GET-kérések állapotát módosító alkalmazások, amelyek változókat vagy erőforrásokat módosítanak, sebezhetők a rosszindulatú támadásokkal szemben. Az állapotot módosító GET-kérelmek nem biztonságosak. Ajánlott eljárás, hogy soha ne változtassunk állapotot GET-kérés során.
A CSRF-támadások a hitelesítéshez cookie-kat használó webalkalmazások ellen lehetségesek, mert:
- A böngészők egy webalkalmazás által kibocsátott cookie-kat tárolnak.
- A tárolt cookie-k munkamenet-cookie-kat tartalmaznak a hitelesített felhasználók számára.
- A böngészők minden, tartományhoz társított cookie-t elküldenek a webalkalmazásnak, függetlenül attól, hogy az alkalmazáskérés hogyan jött létre a böngészőben.
A CSRF-támadások azonban nem korlátozódnak a cookie-k kihasználására. Az alapszintű és a kivonatoló hitelesítés például sebezhető. Miután egy felhasználó bejelentkezett alapszintű vagy kivonatoló hitelesítéssel, a böngésző automatikusan elküldi a hitelesítő adatokat, amíg a munkamenet véget nem ér.
Ebben az összefüggésben munkamenet arra az ügyféloldali munkamenetre vonatkozik, amely során a felhasználó hitelesítése megtörtént. Nem kapcsolódik kiszolgálóoldali munkamenetekhez vagy ASP.NET Core Session Middleware.
A felhasználók óvintézkedéseket tehetnek a CSRF biztonsági rései ellen:
- Kijelentkezés a webalkalmazásból, ha befejezte a használatukat.
- A böngésző cookie-inak rendszeres törlése.
A CSRF biztonsági rései azonban alapvetően a webalkalmazással, nem pedig a végfelhasználóval kapcsolatos problémák.
A hitelesítés alapjai
Cookie-alapú hitelesítés a hitelesítés népszerű formája. A token alapú hitelesítési rendszerek egyre népszerűbbek, különösen az egyoldalas alkalmazások (SPA-k) esetében.
Cookie-alapú hitelesítés
Amikor egy felhasználó a saját felhasználónevével és jelszavával hitelesít, a rendszer egy jogkivonatot ad ki, amely tartalmaz egy hitelesítési jegyet, és ez felhasználható további hitelesítéshez és engedélyezéshez. A tokent egy cookie-ként tárolják, amelyet minden kérésnél az ügyféllel együtt küldenek. A cookie generálását és érvényesítését a Cookie Hitelesítési köztes szoftver végzi. A köztes szoftver egy felhasználónevet titkosított cookieszerializál. A következő kérések során a köztes szoftver ellenőrzi a cookie-t, újra létrehozza a főkomponenst, és hozzárendeli a főkomponenst a HttpContext.User tulajdonsághoz.
Tokenalapú hitelesítés
Ha egy felhasználó hitelesítése megtörtént, a rendszer tokent ad ki (nem pedig antiforgery tokent). A jogkivonat felhasználói adatokat tartalmaz jogcímek formájában, vagy egy hivatkozási jogkivonat formájában, amely az alkalmazást az alkalmazásban fenntartott felhasználói állapotra mutatja. Amikor egy felhasználó megpróbál hozzáférni egy hitelesítést igénylő erőforráshoz, a rendszer a jogkivonatot egy további engedélyezési fejléccel továbbítja az alkalmazásnak tulajdonosi jogkivonat formájában. Ez a megközelítés állapot nélkülivé teszi az alkalmazást. Minden további kérésben a jogkivonat továbbításra kerül a kiszolgálóoldali érvényesítéshez. Ez a jogkivonat nem titkosított; kódolt. A kiszolgálón a rendszer dekódolja a jogkivonatot, hogy hozzáférjen az adataihoz. A jogkivonat későbbi kérésekre való elküldéséhez tárolja a jogkivonatot a böngésző helyi tárolójában. Ha a jogkivonatot a böngésző helyi tárolójában helyezi el, lekérte és tulajdonosi jogkivonatként használja, védelmet nyújt a CSRF-támadások ellen. Ha azonban az alkalmazás sebezhető az XSS-en keresztüli szkriptinjektálással vagy egy feltört külső JavaScript-fájllal, a kibertámadás bármilyen értéket lekérhet a helyi tárolóból, és elküldheti saját magának. ASP.NET Core alapértelmezés szerint a változók összes kiszolgálóoldali kimenetét kódolja, így csökkenti az XSS kockázatát. Ha ezt a viselkedést Html.Raw vagy nem megbízható bemenettel rendelkező egyéni kóddal bírálja felül, akkor növelheti az XSS kockázatát.
Ne aggódjon a CSRF biztonsági rése miatt, ha a jogkivonat a böngésző helyi tárolójában van tárolva. A CSRF aggodalomra ad okot, ha a tokent egy cookie-ban tárolják. További információért lásd a GitHub probléma oldalt: az SPA kódminta két cookie-t ad hozzá.
Több, egy tartományban üzemeltetett alkalmazás
A megosztott üzemeltetési környezetek sebezhetők a munkamenet-eltérítés, a bejelentkezési CSRF és más támadások ellen.
Bár example1.contoso.net
és example2.contoso.net
különböző gazdagépek, implicit megbízhatósági kapcsolat áll fenn a *.contoso.net
tartománybeli gazdagépek között. Ez az implicit megbízhatósági kapcsolat lehetővé teszi, hogy a potenciálisan nem megbízható gazdagépek befolyásolják egymás cookie-jait (az AJAX-kéréseket szabályozó azonos eredetű szabályzatok nem feltétlenül vonatkoznak a HTTP-cookie-kra).
Az ugyanazon a tartományon üzemeltetett alkalmazások közötti megbízható cookie-kat kihasználó támadások megelőzhetők, ha nem osztanak meg tartományokat. Ha az egyes alkalmazásokat a saját tartományában üzemeltetik, nincs kihasználandó implicit cookie megbízhatósági kapcsolat.
Antiforgery az ASP.NET Core-ban
Figyelmeztetés
ASP.NET Core a ASP.NET Core Data Protectionhasználatával implementálja a hamisítás elleni védelmet. Az adatvédelmi vermet úgy kell konfigurálni, hogy egy kiszolgálófarmban működjön. További információért lásd: Az adatvédelem konfigurálása.
Antiforgery middleware kerül be a függőség-injektálási tárolóba, ha az alábbi API-k egyikét meghívják Program.cs
:
A FormTagHelper hamisításgátló tokeneket injektál a HTML-űrlapelemekbe. Egy Razor fájlban a következő korrektúra automatikusan létrehozza az antiforgery tokeneket:
<form method="post">
<!-- ... -->
</form>
Hasonlóképpen, IHtmlHelper.BeginForm alapértelmezés szerint antiforgery tokeneket hoz létre, ha az űrlap metódusa nem GET.
A HTML-űrlapelemek antiforgery tokenjeinek automatikus létrehozása akkor történik, ha a <form>
címke tartalmazza a method="post"
attribútumot, és az alábbiak bármelyike igaz:
- A műveletattribútum üres (
action=""
). - A műveletattribútum nincs megadva (
<form method="post">
).
A HTML-űrlapelemekhez tartozó antiforgery tokenek automatikus létrehozása letiltható:
Explicit módon tiltsa le az antiforgery tokeneket a
asp-antiforgery
attribútummal:<form method="post" asp-antiforgery="false"> <!-- ... --> </form>
Az űrlapelem ki van zárva a Címkesegítők közül a Tag Helper ! opt-out szimbólumokhasználatával.
<!form method="post"> <!-- ... --> </!form>
Távolítsa el a
FormTagHelper
a nézetből. AFormTagHelper
eltávolítható egy nézetből az alábbi irányelv Razor nézethez való hozzáadásával:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Jegyzet
Razor lapok automatikusan védettek az XSRF/CSRF támadások ellen. További információ: XSRF/CSRF és Razor Pages.
A CSRF-támadások elleni védelem leggyakoribb módja a szinkronizáló jogkivonat-minta (STP) használata. Az STP akkor használatos, ha a felhasználó űrlapadatokat tartalmazó lapot kér:
- A kiszolgáló egy jogkivonatot küld a kliensnek, amely az aktuális felhasználó identitásához van társítva.
- Az ügyfél visszaküldi a jogkivonatot a kiszolgálónak ellenőrzés céljából.
- Ha a kiszolgáló olyan jogkivonatot kap, amely nem egyezik a hitelesített felhasználó identitásával, a rendszer elutasítja a kérést.
A token egyedi és kiszámíthatatlan. A jogkivonat arra is használható, hogy biztosítsa a kérelmek sorozatának megfelelő sorrendjét (például a következő kérelmek sorrendjének biztosításához: 1. oldal > 2. oldal > 3. oldal). Az összes ASP.NET Core MVC és Razor Pages sablonú űrlap valahogy antiforgery tokeneket hoz létre. A következő példanézet-páros antiforgery biztonsági tokeneket hoz létre:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
Kifejezetten adjon hozzá egy hamisítás elleni tokent egy <form>
elemhez a Tag Helper és a HTML-segéd használata nélkül @Html.AntiForgeryToken
.
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Az előző esetekben ASP.NET Core az alábbi példához hasonló rejtett űrlapmezőt ad hozzá:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core három szűrőt tartalmaz, az antiforgery tokenek használatát:
Hamisításvédelem AddControllers
A AddControllers hívása nem engedélyezni az antiforgery tokeneket. A AddControllersWithViews-t meg kell hívni, hogy beépített hamisításgátló token-támogatással rendelkezzen.
Több böngészőlap és a szinkronizáló token sablon
A Szinkronizáló Token Mintázat esetében csak a legutóbb betöltött oldal tartalmaz érvényes hamisítás elleni tokent. Több lap használata problémás lehet. Ha például egy felhasználó több lapot nyit meg:
- Csak a legutóbb betöltött lap tartalmaz érvényes antiforgery tokent.
- A korábban betöltött lapokról érkező kérések hiba miatt meghiúsulnak:
Antiforgery token validation failed. The antiforgery cookie token and request token do not match
Ha ez problémát okoz, fontolja meg az alternatív CSRF-védelmi mintákat.
Antiforgery konfigurálása AntiforgeryOptions
AntiforgeryOptions testreszabása a Program.cs
-en:
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Állítsa be az antiforgery Cookie
tulajdonságokat a CookieBuilder osztály tulajdonságaival, ahogyan az az alábbi táblázatban látható.
Opció | Leírás |
---|---|
Cookie | Meghatározza az antiforgery cookie-k létrehozásához használt beállításokat. |
FormFieldName | Annak a rejtett űrlapmezőnek a neve, amelyet az antiforgery rendszer használ az antiforgery tokenek nézetekben való megjelenítéséhez. |
HeaderName | Az antiforgery rendszer által használt fejléc neve. Ha null , a rendszer csak az űrlapadatokat veszi figyelembe. |
SuppressXFrameOptionsHeader | Megadja, hogy el kívánja-e tiltani a X-Frame-Options fejléc generálását. Alapértelmezés szerint a fejléc "SAMEORIGIN" értékkel jön létre. Alapértelmezés szerint false . |
További információ: CookieAuthenticationOptions.
Antiforgery tokenek létrehozása IAntiforgery
IAntiforgery biztosítja az API-t az antiforgery funkciók konfigurálásához.
IAntiforgery
a Program.cs
használatával kérhető meg WebApplication.Services-ben. Az alábbi példa az alkalmazás kezdőlapjáról származó köztes szoftvereket használ egy antiforgery jogkivonat létrehozásához, és cookieként küldi el a válaszba:
app.UseRouting();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
}
return next(context);
});
Az előző példa egy cookie nevű XSRF-TOKEN
-et állít be. Az ügyfél elolvashatja ezt a cookie, és az AJAX-kérelmekhez csatolt fejlécként megadhatja az értékét. Az Angular például beépített XSRF-védelmet tartalmaz, amely alapértelmezés szerint egy cookie nevű XSRF-TOKEN
-t olvas be.
Hamisítás elleni ellenőrzés megkövetelése
Az ValidateAntiForgeryToken műveletszűrő egyéni műveletekre, vezérlőkre vagy globálisan alkalmazható. A szűrőt alkalmazó műveletekre irányuló kérések le lesznek tiltva, kivéve, ha a kérés érvényes antiforgery-jogkivonatot tartalmaz:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
A ValidateAntiForgeryToken
attribútumhoz jogkivonatra van szükség az általa jelölt műveleti módszerekre irányuló kérelmekhez, beleértve a HTTP GET-kérelmeket is. Ha az alkalmazás vezérlőire a ValidateAntiForgeryToken
attribútum van alkalmazva, akkor a IgnoreAntiforgeryToken
attribútummal felülírható.
Az antiforgery tokenek automatikus ellenőrzése csak a nem biztonságos HTTP-metódusok esetén történik meg.
Ahelyett, hogy a ValidateAntiForgeryToken
attribútumot általánosan alkalmazná, majd felülírná IgnoreAntiforgeryToken
attribútumokkal, az AutoValidateAntiforgeryToken attribútum használható. Ez az attribútum ugyanúgy működik, mint a ValidateAntiForgeryToken
attribútum, azzal a különbségkel, hogy nem igényel jogkivonatokat a következő HTTP-metódusokkal végrehajtott kérelmekhez:
- SZEREZZ
- FEJ
- OPCIÓK
- NYOM
Javasoljuk a AutoValidateAntiforgeryToken
széles körű használatát nem API-szcenáriókhoz. Ez az attribútum biztosítja, hogy a POST-műveletek alapértelmezés szerint védettek legyenek. A másik lehetőség az, hogy alapértelmezés szerint figyelmen kívül hagyja az antiforgery tokeneket, kivéve, ha ValidateAntiForgeryToken
az egyes műveleti módszerekre van alkalmazva. Ebben a forgatókönyvben valószínűbb, hogy egy POST-műveletmetódus véletlenül védtelen marad, így az alkalmazás sebezhető lesz a CSRF-támadásokkal szemben. Minden POST-nak el kell küldenie a hamisítás elleni tokent.
Az API-k nem rendelkeznek automatikus mechanizmusokkal a jogkivonat nemcookie részének küldéséhez. A megvalósítás valószínűleg az ügyfélkód implementálásától függ. Néhány példa alább látható:
Osztályszintű példa:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Globális példa:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Globális vagy vezérlő antiforgery attribútumok felülbírálása
Az IgnoreAntiforgeryToken szűrővel kiküszöbölhető az adott művelethez (vagy vezérlőhöz) tartozó antiforgery token szükségessége. Alkalmazásakor ez a szűrő felülbírálja a magasabb szinten (globálisan vagy vezérlőn) megadott ValidateAntiForgeryToken
és AutoValidateAntiforgeryToken
szűrőket.
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Jogkivonatok frissítése a hitelesítés után
A tokeneket a felhasználó hitelesítése után frissíteni kell úgy, hogy a felhasználót átirányítja egy felületre vagy Razor Pages oldalra.
JavaScript, AJAX és SLA-k
Hagyományos HTML-alapú alkalmazásokban rejtett űrlapmezőkön keresztül továbbítják az antiforgery jogkivonatokat a kiszolgálónak. A modern JavaScript-alapú alkalmazásokban és SLA-kban számos kérés programozott módon történik. Ezek az AJAX-kérések más technikákat (például kérésfejléceket vagy cookie-kat) is használhatnak a jogkivonat elküldéséhez.
Ha a cookie-kat hitelesítési jogkivonatok tárolására és API-kérések hitelesítésére használják a kiszolgálón, a CSRF potenciális probléma. Ha a helyi tárolót a jogkivonat tárolására használják, a CSRF biztonsági rése csökkenthető, mivel a rendszer nem küldi el automatikusan a helyi tárolóból származó értékeket a kiszolgálónak minden kéréssel együtt. A helyi tároló használata az antiforgery token ügyfélen való tárolására és a token kérésfejlécben történő elküldésére ajánlott módszer.
JavaScript
JavaScript nézetek használata esetén az azonosító egy szolgáltatás segítségével hozható létre a nézeten belül. Injektálja a IAntiforgery szolgáltatást a nézetbe, és hívja meg GetAndStoreTokens:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
@{
ViewData["Title"] = "JavaScript";
var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
<input id="RequestVerificationToken" type="hidden" value="@requestToken" />
<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", () => {
const resultElement = document.getElementById("result");
document.getElementById("button").addEventListener("click", async () => {
const response = await fetch("@Url.Action("FetchEndpoint")", {
method: "POST",
headers: {
RequestVerificationToken:
document.getElementById("RequestVerificationToken").value
}
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
});
});
</script>
}
Az előző példa JavaScript használatával olvassa be az AJAX POST fejléc rejtett mezőértékét.
Ez a megközelítés szükségtelenné teszi a cookie-k szerverről történő közvetlen beállítását vagy kliensről való közvetlen olvasását. Amikor azonban a IAntiforgery szolgáltatás injektálása nem lehetséges, használja a JavaScriptet a jogkivonatok eléréséhez a cookie-kban.
- Hozzáférési jogkivonatok a kiszolgálóra irányuló további kérésekben, általában
same-origin
. - A cookietartalmát felhasználva hozzon létre egy fejlécet a token értékével.
Feltéve, hogy a szkript egy X-XSRF-TOKEN
nevű kérelemfejlécben küldi el a jogkivonatot, konfigurálja az antiforgery szolgáltatást a X-XSRF-TOKEN
fejléc keresésére:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Az alábbi példa hozzáad egy védett végpontot, amely a kérés jogkivonatát egy JavaScript által olvasható cookie-ba írja.
app.UseAuthorization();
app.MapGet("antiforgery/token", (IAntiforgery forgeryService, HttpContext context) =>
{
var tokens = forgeryService.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.Ok();
}).RequireAuthorization();
Az alábbi példa JavaScript használatával küld egy AJAX-kérést a token megszerzésére, és egy másik kérést a megfelelő fejléc alkalmazásával.
var response = await fetch("/antiforgery/token", {
method: "GET",
headers: { "Authorization": authorizationToken }
});
if (response.ok) {
// https://developer.mozilla.org/docs/web/api/document/cookie
const xsrfToken = document.cookie
.split("; ")
.find(row => row.startsWith("XSRF-TOKEN="))
.split("=")[1];
response = await fetch("/JavaScript/FetchEndpoint", {
method: "POST",
headers: { "X-XSRF-TOKEN": xsrfToken, "Authorization": authorizationToken }
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
Jegyzet
Ha az antiforgery token mind a kérelem fejlécben, mind az űrlap hasznos adataiban szerepel, csak a fejlécben lévő token kerül érvényesítésre.
Az API-k minimálisra csökkentésével történő csalás elleni védelem
Minimal APIs
nem támogatják a mellékelt szűrők (ValidateAntiForgeryToken
, AutoValidateAntiforgeryToken
, IgnoreAntiforgeryToken
) használatát, azonban IAntiforgery biztosítja a kérések érvényesítéséhez szükséges API-kat.
Az alábbi példa létrehoz egy szűrőt, amely ellenőrzi az antiforgery tokent:
internal static class AntiForgeryExtensions
{
public static TBuilder ValidateAntiforgery<TBuilder>(this TBuilder builder) where TBuilder : IEndpointConventionBuilder
{
return builder.AddEndpointFilter(routeHandlerFilter: async (context, next) =>
{
try
{
var antiForgeryService = context.HttpContext.RequestServices.GetRequiredService<IAntiforgery>();
await antiForgeryService.ValidateRequestAsync(context.HttpContext);
}
catch (AntiforgeryValidationException)
{
return Results.BadRequest("Antiforgery token validation failed.");
}
return await next(context);
});
}
}
A szűrő ezután alkalmazható egy végpontra:
app.MapPost("api/upload", (IFormFile name) => Results.Accepted())
.RequireAuthorization()
.ValidateAntiforgery();
Windows-hitelesítés és hamisítást gátló sütik
A Windows-hitelesítés használatakor az alkalmazásvégpontokat ugyanúgy kell védeni a CSRF-támadások ellen, mint a cookie-k esetében. A böngésző implicit módon elküldi a hitelesítési környezetet a kiszolgálónak, és a végpontokat védeni kell a CSRF-támadások ellen.
Antiforgery kiterjesztése
A IAntiforgeryAdditionalDataProvider típus lehetővé teszi a fejlesztők számára a CSRF-ellenes rendszer viselkedésének kiterjesztését az egyes tokenekben történő további adatcserével. A GetAdditionalData metódust minden alkalommal meghívják, amikor létrehoz egy mezőt, és a visszatérési érték a létrehozott mezőben van beágyazva. A megvalósító visszaadhat egy időbélyeget, egy egyedi azonosítót vagy bármilyen más értéket, majd meghívhatja a ValidateAdditionalData függvényt, amikor a jogkivonat érvényesítésre kerül, hogy érvényesítse ezeket az adatokat. Az ügyfél felhasználóneve már be van ágyazva a létrehozott tokenekbe, így nincs szükség ezen információk külön feltüntetésére. Ha egy token kiegészítő adatokat tartalmaz, de nincs konfigurálva IAntiForgeryAdditionalDataProvider
, akkor a kiegészítő adatokat nem érvényesítik.
További erőforrások
A webhelyek közötti kérelemhamisítás (más néven XSRF vagy CSRF) a webalkalmazások elleni támadás, amelynek során egy rosszindulatú webalkalmazás befolyásolhatja az ügyfélböngésző és az a böngésző által megbízhatónak tartott webalkalmazás közötti interakciót. Ezek a támadások azért lehetségesek, mert a webböngészők minden kéréssel automatikusan küldenek bizonyos hitelesítési jogkivonatokat egy webhelyre. Ezt a biztonsági rést egykattintásos támadásnak is nevezik, vagy munkamenet-eltérítésnek, mert kihasználja a felhasználó korábban hitelesített munkamenetét.
Példa CSRF-támadásra:
A felhasználó űrlap-hitelesítéssel jelentkezik be
www.good-banking-site.example.com
. A kiszolgáló hitelesíti a felhasználót, és egy hitelesítési cookietartalmazó választ ad ki. A webhely sebezhető a támadásokkal szemben, mert megbízik minden olyan kérésben, amelyet érvényes hitelesítési cookiekap.A felhasználó meglátogat egy rosszindulatú webhelyet,
www.bad-crook-site.example.com
.A kártékony webhely (
www.bad-crook-site.example.com
) az alábbi példához hasonló HTML-űrlapot tartalmaz:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>
Figyelje meg, hogy az űrlap
action
a sebezhető webhelyre, nem pedig a rosszindulatú webhelyre. Ez a CSRF "keresztoldali" része.A felhasználó kiválasztja a Küldés gombot. A böngésző a kérést végrehajtja, és automatikusan tartalmazza a cookie hitelesítést a kért tartományhoz,
www.good-banking-site.example.com
.A kérés a
www.good-banking-site.example.com
kiszolgálón fut a felhasználó hitelesítési környezetével, és bármilyen műveletet végrehajthat, amelyet egy hitelesített felhasználó végrehajthat.
Azon forgatókönyv mellett, amikor a felhasználó kiválasztja az űrlap elküldéséhez a gombot, a rosszindulatú webhely a következőt teheti:
- Futtasson egy szkriptet, amely automatikusan elküldi az űrlapot.
- Küldje el az űrlap beküldését AJAX-kérelemként.
- Rejtse el az űrlapot a CSS használatával.
Ezek az alternatív forgatókönyvek nem igényelnek semmilyen műveletet vagy bemenetet a felhasználótól, kivéve, ha eredetileg meglátogatják a rosszindulatú webhelyet.
A HTTPS használata nem akadályozza meg a CSRF-támadást. A rosszindulatú webhely ugyanúgy küldhet https://www.good-banking-site.example.com/
kérést, mint egy nem biztonságos kérést.
Egyes támadások a GET-kérelmekre reagáló végpontokat támadják meg, ebben az esetben egy képcímke használható a művelet végrehajtásához. Ez a támadási forma gyakori a fórumwebhelyeken, amelyek lehetővé teszik a képeket, de letiltják a JavaScriptet. A GET-kérések állapotát módosító alkalmazások, amelyek változókat vagy erőforrásokat módosítanak, sebezhetők a rosszindulatú támadásokkal szemben. Az állapotot módosító GET-kérelmek nem biztonságosak. Ajánlott eljárás, hogy soha ne változtassunk állapotot GET-kérés során.
A CSRF-támadások a hitelesítéshez cookie-kat használó webalkalmazások ellen lehetségesek, mert:
- A böngészők egy webalkalmazás által kibocsátott cookie-kat tárolnak.
- A tárolt cookie-k munkamenet-cookie-kat tartalmaznak a hitelesített felhasználók számára.
- A böngészők minden, tartományhoz társított cookie-t elküldenek a webalkalmazásnak, függetlenül attól, hogy az alkalmazáskérés hogyan jött létre a böngészőben.
A CSRF-támadások azonban nem korlátozódnak a cookie-k kihasználására. Az alapszintű és a kivonatoló hitelesítés például sebezhető. Miután egy felhasználó bejelentkezett alapszintű vagy kivonatoló hitelesítéssel, a böngésző automatikusan elküldi a hitelesítő adatokat, amíg a munkamenet véget nem ér.
Ebben az összefüggésben munkamenet arra az ügyféloldali munkamenetre vonatkozik, amely során a felhasználó hitelesítése megtörtént. Nem kapcsolódik kiszolgálóoldali munkamenetekhez vagy ASP.NET Core Session Middleware.
A felhasználók óvintézkedéseket tehetnek a CSRF biztonsági rései ellen:
- Kijelentkezés a webalkalmazásból, ha befejezte a használatukat.
- A böngésző cookie-inak rendszeres törlése.
A CSRF biztonsági rései azonban alapvetően a webalkalmazással, nem pedig a végfelhasználóval kapcsolatos problémák.
A hitelesítés alapjai
Cookie-alapú hitelesítés a hitelesítés népszerű formája. A token alapú hitelesítési rendszerek egyre népszerűbbek, különösen az egyoldalas alkalmazások (SPA-k) esetében.
Cookie-alapú hitelesítés
Amikor egy felhasználó a saját felhasználónevével és jelszavával hitelesít, a rendszer egy jogkivonatot ad ki, amely tartalmaz egy hitelesítési jegyet, és ez felhasználható további hitelesítéshez és engedélyezéshez. A tokent egy cookie-ként tárolják, amelyet minden kérésnél az ügyféllel együtt küldenek. A cookie generálását és érvényesítését a Cookie Hitelesítési köztes szoftver végzi. A köztes szoftver egy felhasználónevet titkosított cookieszerializál. A következő kérések során a köztes szoftver ellenőrzi a cookie-t, újra létrehozza a főkomponenst, és hozzárendeli a főkomponenst a HttpContext.User tulajdonsághoz.
Tokenalapú hitelesítés
Ha egy felhasználó hitelesítése megtörtént, a rendszer tokent ad ki (nem pedig antiforgery tokent). A jogkivonat felhasználói adatokat tartalmaz jogcímek formájában, vagy egy hivatkozási jogkivonat formájában, amely az alkalmazást az alkalmazásban fenntartott felhasználói állapotra mutatja. Amikor egy felhasználó megpróbál hozzáférni egy hitelesítést igénylő erőforráshoz, a rendszer a jogkivonatot egy további engedélyezési fejléccel továbbítja az alkalmazásnak tulajdonosi jogkivonat formájában. Ez a megközelítés állapot nélkülivé teszi az alkalmazást. Minden további kérésben a jogkivonat továbbításra kerül a kiszolgálóoldali érvényesítéshez. Ez a jogkivonat nem titkosított; kódolt. A kiszolgálón a rendszer dekódolja a jogkivonatot, hogy hozzáférjen az adataihoz. A jogkivonat későbbi kérésekre való elküldéséhez tárolja a jogkivonatot a böngésző helyi tárolójában. Ne aggódjon a CSRF biztonsági rése miatt, ha a jogkivonat a böngésző helyi tárolójában van tárolva. A CSRF aggodalomra ad okot, ha a tokent egy cookie-ban tárolják. További információért lásd a GitHub probléma oldalt: az SPA kódminta két cookie-t ad hozzá.
Több, egy tartományban üzemeltetett alkalmazás
A megosztott üzemeltetési környezetek sebezhetők a munkamenet-eltérítés, a bejelentkezési CSRF és más támadások ellen.
Bár example1.contoso.net
és example2.contoso.net
különböző gazdagépek, implicit megbízhatósági kapcsolat áll fenn a *.contoso.net
tartománybeli gazdagépek között. Ez az implicit megbízhatósági kapcsolat lehetővé teszi, hogy a potenciálisan nem megbízható gazdagépek befolyásolják egymás cookie-jait (az AJAX-kéréseket szabályozó azonos eredetű szabályzatok nem feltétlenül vonatkoznak a HTTP-cookie-kra).
Az ugyanazon a tartományon üzemeltetett alkalmazások közötti megbízható cookie-kat kihasználó támadások megelőzhetők, ha nem osztanak meg tartományokat. Ha az egyes alkalmazásokat a saját tartományában üzemeltetik, nincs kihasználandó implicit cookie megbízhatósági kapcsolat.
Antiforgery az ASP.NET Core-ban
Figyelmeztetés
ASP.NET Core a ASP.NET Core Data Protectionhasználatával implementálja a hamisítás elleni védelmet. Az adatvédelmi vermet úgy kell konfigurálni, hogy egy kiszolgálófarmban működjön. További információért lásd: Az adatvédelem konfigurálása.
Antiforgery middleware kerül be a függőség-injektálási tárolóba, ha az alábbi API-k egyikét meghívják Program.cs
:
A FormTagHelper hamisításgátló tokeneket injektál a HTML-űrlapelemekbe. Egy Razor fájlban a következő korrektúra automatikusan létrehozza az antiforgery tokeneket:
<form method="post">
<!-- ... -->
</form>
Hasonlóképpen, IHtmlHelper.BeginForm alapértelmezés szerint antiforgery tokeneket hoz létre, ha az űrlap metódusa nem GET.
A HTML-űrlapelemek antiforgery tokenjeinek automatikus létrehozása akkor történik, ha a <form>
címke tartalmazza a method="post"
attribútumot, és az alábbiak bármelyike igaz:
- A műveletattribútum üres (
action=""
). - A műveletattribútum nincs megadva (
<form method="post">
).
A HTML-űrlapelemekhez tartozó antiforgery tokenek automatikus létrehozása letiltható:
Explicit módon tiltsa le az antiforgery tokeneket a
asp-antiforgery
attribútummal:<form method="post" asp-antiforgery="false"> <!-- ... --> </form>
Az űrlapelem ki van zárva a Címkesegítők közül a Tag Helper ! opt-out szimbólumokhasználatával.
<!form method="post"> <!-- ... --> </!form>
Távolítsa el a
FormTagHelper
a nézetből. AFormTagHelper
eltávolítható egy nézetből az alábbi irányelv Razor nézethez való hozzáadásával:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Jegyzet
Razor lapok automatikusan védettek az XSRF/CSRF támadások ellen. További információ: XSRF/CSRF és Razor Pages.
A CSRF-támadások elleni védelem leggyakoribb módja a szinkronizáló jogkivonat-minta (STP) használata. Az STP akkor használatos, ha a felhasználó űrlapadatokat tartalmazó lapot kér:
- A kiszolgáló az aktuális felhasználó identitásához társított jogkivonatot küld a kliensnek.
- Az ügyfél visszaküldi a jogkivonatot a kiszolgálónak ellenőrzés céljából.
- Ha a kiszolgáló olyan jogkivonatot kap, amely nem egyezik a hitelesített felhasználó identitásával, a rendszer elutasítja a kérést.
A token egyedi és kiszámíthatatlan. A jogkivonat arra is használható, hogy biztosítsa a kérelmek sorozatának megfelelő sorrendjét (például a következő kérelmek sorrendjének biztosításához: 1. oldal > 2. oldal > 3. oldal). Az összes ASP.NET Core MVC és Razor Pages sablonú űrlap valahogy antiforgery tokeneket hoz létre. A következő példanézet-páros antiforgery biztonsági tokeneket hoz létre:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
Kifejezetten adjon hozzá egy hamisítás elleni tokent egy <form>
elemhez a Tag Helper és a HTML-segéd használata nélkül @Html.AntiForgeryToken
.
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Az előző esetekben ASP.NET Core az alábbi példához hasonló rejtett űrlapmezőt ad hozzá:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core három szűrőt tartalmaz, az antiforgery tokenek használatát:
Hamisítás elleni védelem az AddControllers használatával
A AddControllers hívása nem engedélyezni az antiforgery tokeneket. A AddControllersWithViews-t meg kell hívni, hogy beépített hamisításgátló token-támogatással rendelkezzen.
Több böngészőlap és a szinkronizáló token sablon
A Szinkronizáló Token Mintázat esetében csak a legutóbb betöltött oldal tartalmaz érvényes hamisítás elleni tokent. Több lap használata problémás lehet. Ha például egy felhasználó több lapot nyit meg:
- Csak a legutóbb betöltött lap tartalmaz érvényes antiforgery tokent.
- A korábban betöltött lapokról érkező kérések hiba miatt meghiúsulnak:
Antiforgery token validation failed. The antiforgery cookie token and request token do not match
Ha ez problémát okoz, fontolja meg az alternatív CSRF-védelmi mintákat.
Antiforgery konfigurálása AntiforgeryOptions
AntiforgeryOptions testreszabása a Program.cs
-en:
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Állítsa be az antiforgery Cookie
tulajdonságokat a CookieBuilder osztály tulajdonságaival, ahogyan az az alábbi táblázatban látható.
Opció | Leírás |
---|---|
Cookie | Meghatározza az antiforgery cookie-k létrehozásához használt beállításokat. |
FormFieldName | Annak a rejtett űrlapmezőnek a neve, amelyet az antiforgery rendszer használ az antiforgery tokenek nézetekben való megjelenítéséhez. |
HeaderName | Az antiforgery rendszer által használt fejléc neve. Ha null , a rendszer csak az űrlapadatokat veszi figyelembe. |
SuppressXFrameOptionsHeader | Megadja, hogy el kívánja-e tiltani a X-Frame-Options fejléc generálását. Alapértelmezés szerint a fejléc "SAMEORIGIN" értékkel jön létre. Alapértelmezés szerint false . |
További információ: CookieAuthenticationOptions.
Antiforgery tokenek létrehozása IAntiforgery
IAntiforgery biztosítja az API-t az antiforgery funkciók konfigurálásához.
IAntiforgery
a Program.cs
használatával kérhető meg WebApplication.Services-ben. Az alábbi példa az alkalmazás kezdőlapján található köztes szoftvert használja egy antiforgery token létrehozásához, és a válasz részeként küldi el mint cookie.
app.UseRouting();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
}
return next(context);
});
Az előző példa egy cookie nevű XSRF-TOKEN
-et állít be. Az ügyfél elolvashatja ezt a cookie, és az AJAX-kérelmekhez csatolt fejlécként megadhatja az értékét. Az Angular például beépített XSRF-védelmet tartalmaz, amely alapértelmezés szerint egy cookie nevű XSRF-TOKEN
-t olvas be.
Hamisítás elleni ellenőrzés megkövetelése
Az ValidateAntiForgeryToken műveletszűrő egyéni műveletekre, vezérlőkre vagy globálisan alkalmazható. A szűrőt alkalmazó műveletekre irányuló kérések le lesznek tiltva, kivéve, ha a kérés érvényes antiforgery-jogkivonatot tartalmaz:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
A ValidateAntiForgeryToken
attribútumhoz jogkivonatra van szükség az általa jelölt műveleti módszerekre irányuló kérelmekhez, beleértve a HTTP GET-kérelmeket is. Ha az alkalmazás vezérlőire a ValidateAntiForgeryToken
attribútum van alkalmazva, akkor a IgnoreAntiforgeryToken
attribútummal felülírható.
Az antiforgery tokenek automatikus ellenőrzése csak a nem biztonságos HTTP-metódusok esetén történik meg.
Ahelyett, hogy a ValidateAntiForgeryToken
attribútumot általánosan alkalmazná, majd felülírná IgnoreAntiforgeryToken
attribútumokkal, az AutoValidateAntiforgeryToken attribútum használható. Ez az attribútum ugyanúgy működik, mint a ValidateAntiForgeryToken
attribútum, azzal a különbségkel, hogy nem igényel jogkivonatokat a következő HTTP-metódusokkal végrehajtott kérelmekhez:
- SZEREZZ
- FEJ
- OPCIÓK
- NYOM
Javasoljuk a AutoValidateAntiforgeryToken
széles körű használatát nem API-szcenáriókhoz. Ez az attribútum biztosítja, hogy a POST-műveletek alapértelmezés szerint védettek legyenek. A másik lehetőség az, hogy alapértelmezés szerint figyelmen kívül hagyja az antiforgery tokeneket, kivéve, ha ValidateAntiForgeryToken
az egyes műveleti módszerekre van alkalmazva. Ebben a forgatókönyvben valószínűbb, hogy egy POST-műveletmetódus véletlenül védtelen marad, így az alkalmazás sebezhető lesz a CSRF-támadásokkal szemben. Minden POST-nak el kell küldenie a hamisítás elleni tokent.
Az API-k nem rendelkeznek automatikus mechanizmusokkal a jogkivonat nemcookie részének küldéséhez. A megvalósítás valószínűleg az ügyfélkód implementálásától függ. Néhány példa alább látható:
Osztályszintű példa:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Globális példa:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Globális vagy vezérlő antiforgery attribútumok felülbírálása
Az IgnoreAntiforgeryToken szűrővel kiküszöbölhető az adott művelethez (vagy vezérlőhöz) tartozó antiforgery token szükségessége. Alkalmazásakor ez a szűrő felülbírálja a magasabb szinten (globálisan vagy vezérlőn) megadott ValidateAntiForgeryToken
és AutoValidateAntiforgeryToken
szűrőket.
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Jogkivonatok frissítése a hitelesítés után
A tokeneket a felhasználó hitelesítése után frissíteni kell úgy, hogy a felhasználót átirányítja egy felületre vagy Razor Pages oldalra.
JavaScript, AJAX és SLA-k
Hagyományos HTML-alapú alkalmazásokban rejtett űrlapmezőkön keresztül továbbítják az antiforgery jogkivonatokat a kiszolgálónak. A modern JavaScript-alapú alkalmazásokban és SLA-kban számos kérés programozott módon történik. Ezek az AJAX-kérések más technikákat (például kérésfejléceket vagy cookie-kat) is használhatnak a jogkivonat elküldéséhez.
Ha a cookie-kat hitelesítési jogkivonatok tárolására és API-kérések hitelesítésére használják a kiszolgálón, a CSRF potenciális probléma. Ha a helyi tárolót a jogkivonat tárolására használják, a CSRF biztonsági rése csökkenthető, mivel a rendszer nem küldi el automatikusan a helyi tárolóból származó értékeket a kiszolgálónak minden kéréssel együtt. A helyi tároló használata az antiforgery token ügyfélen való tárolására és a token kérésfejlécben történő elküldésére ajánlott módszer.
JavaScript
JavaScript nézetek használata esetén az azonosító egy szolgáltatás segítségével hozható létre a nézeten belül. Injektálja a IAntiforgery szolgáltatást a nézetbe, és hívja meg GetAndStoreTokens:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
@{
ViewData["Title"] = "JavaScript";
var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
<input id="RequestVerificationToken" type="hidden" value="@requestToken" />
<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", () => {
const resultElement = document.getElementById("result");
document.getElementById("button").addEventListener("click", async () => {
const response = await fetch("@Url.Action("FetchEndpoint")", {
method: "POST",
headers: {
RequestVerificationToken:
document.getElementById("RequestVerificationToken").value
}
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
});
});
</script>
}
Az előző példa JavaScript használatával olvassa be az AJAX POST fejléc rejtett mezőértékét.
Ez a megközelítés szükségtelenné teszi a cookie-k szerverről történő közvetlen beállítását vagy kliensről való közvetlen olvasását. Ha azonban a IAntiforgery szolgáltatás injektálása nem lehetséges, a JavaScript a cookie-kban is hozzáférhet a jogkivonathoz, amely a kiszolgálóhoz érkező további kérésből (általában same-origin
) származik, és a cookietartalmának használatával létrehozhat egy fejlécet a jogkivonat értékével.
Feltéve, hogy a szkript egy X-XSRF-TOKEN
nevű kérelemfejlécben küldi el a jogkivonatot, konfigurálja az antiforgery szolgáltatást a X-XSRF-TOKEN
fejléc keresésére:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Az alábbi példa hozzáad egy védett végpontot, amely a kérés jogkivonatát egy JavaScript által olvasható módon a cookie-ba írja.
app.UseAuthorization();
app.MapGet("antiforgery/token", (IAntiforgery forgeryService, HttpContext context) =>
{
var tokens = forgeryService.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.Ok();
}).RequireAuthorization();
Az alábbi példa JavaScript használatával küld egy AJAX-kérést a token megszerzésére, és egy másik kérést a megfelelő fejléc alkalmazásával.
var response = await fetch("/antiforgery/token", {
method: "GET",
headers: { "Authorization": authorizationToken }
});
if (response.ok) {
// https://developer.mozilla.org/docs/web/api/document/cookie
const xsrfToken = document.cookie
.split("; ")
.find(row => row.startsWith("XSRF-TOKEN="))
.split("=")[1];
response = await fetch("/JavaScript/FetchEndpoint", {
method: "POST",
headers: { "X-XSRF-TOKEN": xsrfToken, "Authorization": authorizationToken }
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
Windows-hitelesítés és hamisítást gátló sütik
A Windows-hitelesítés használatakor az alkalmazásvégpontokat ugyanúgy kell védeni a CSRF-támadások ellen, mint a cookie-k esetében. A böngésző implicit módon elküldi a hitelesítési környezetet a kiszolgálónak, ezért a végpontokat védeni kell a CSRF-támadások ellen.
Antiforgery kiterjesztése
A IAntiforgeryAdditionalDataProvider típus lehetővé teszi a fejlesztők számára a CSRF-ellenes rendszer viselkedésének kiterjesztését az egyes tokenekben történő további adatcserével. A GetAdditionalData metódust minden alkalommal meghívják, amikor létrehoz egy mezőt, és a visszatérési érték a létrehozott mezőben van beágyazva. A megvalósító visszaadhat egy időbélyeget, egy egyedi azonosítót vagy bármilyen más értéket, majd meghívhatja a ValidateAdditionalData függvényt, amikor a jogkivonat érvényesítésre kerül, hogy érvényesítse ezeket az adatokat. Az ügyfél felhasználóneve már be van ágyazva a létrehozott tokenekbe, így nincs szükség ezen információk külön feltüntetésére. Ha egy token kiegészítő adatokat tartalmaz, de nincs konfigurálva IAntiForgeryAdditionalDataProvider
, akkor a kiegészítő adatokat nem érvényesítik.
További erőforrások
A webhelyek közötti kérelemhamisítás (más néven XSRF vagy CSRF) a webalkalmazások elleni támadás, amelynek során egy rosszindulatú webalkalmazás befolyásolhatja az ügyfélböngésző és az a böngésző által megbízhatónak tartott webalkalmazás közötti interakciót. Ezek a támadások azért lehetségesek, mert a webböngészők minden kéréssel automatikusan küldenek bizonyos hitelesítési jogkivonatokat egy webhelyre. Ezt a biztonsági rést egykattintásos támadásnak is nevezik, vagy munkamenet-eltérítésnek, mert kihasználja a felhasználó korábban hitelesített munkamenetét.
Példa CSRF-támadásra:
A felhasználó űrlap-hitelesítéssel jelentkezik be
www.good-banking-site.example.com
. A kiszolgáló hitelesíti a felhasználót, és egy hitelesítési cookietartalmazó választ ad ki. A webhely sebezhető a támadásokkal szemben, mert megbízik minden olyan kérésben, amelyet érvényes hitelesítési cookiekap.A felhasználó meglátogat egy rosszindulatú webhelyet,
www.bad-crook-site.example.com
.A kártékony webhely (
www.bad-crook-site.example.com
) az alábbi példához hasonló HTML-űrlapot tartalmaz:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>
Figyelje meg, hogy az űrlap
action
a sebezhető webhelyre, nem pedig a rosszindulatú webhelyre. Ez a CSRF "keresztoldali" része.A felhasználó kiválasztja a Küldés gombot. A böngésző a kérést végrehajtja, és automatikusan tartalmazza a cookie hitelesítést a kért tartományhoz,
www.good-banking-site.example.com
.A kérés a
www.good-banking-site.example.com
kiszolgálón fut a felhasználó hitelesítési környezetével, és bármilyen műveletet végrehajthat, amelyet egy hitelesített felhasználó végrehajthat.
Azon forgatókönyv mellett, amikor a felhasználó kiválasztja az űrlap elküldéséhez a gombot, a rosszindulatú webhely a következőt teheti:
- Futtasson egy szkriptet, amely automatikusan elküldi az űrlapot.
- Küldje el az űrlap beküldését AJAX-kérelemként.
- Rejtse el az űrlapot a CSS használatával.
Ezek az alternatív forgatókönyvek nem igényelnek semmilyen műveletet vagy bemenetet a felhasználótól, kivéve, ha eredetileg meglátogatják a rosszindulatú webhelyet.
A HTTPS használata nem akadályozza meg a CSRF-támadást. A rosszindulatú webhely ugyanolyan könnyen küldhet egy https://www.good-banking-site.example.com/
kérést, mint egy nem biztonságos kérést.
Egyes támadások a GET-kérelmekre reagáló végpontokat támadják meg, ebben az esetben egy képcímke használható a művelet végrehajtásához. Ez a támadási forma gyakori a fórumwebhelyeken, amelyek lehetővé teszik a képeket, de letiltják a JavaScriptet. A GET-kérések állapotát módosító alkalmazások, amelyek változókat vagy erőforrásokat módosítanak, sebezhetők a rosszindulatú támadásokkal szemben. Az állapotot módosító GET-kérelmek nem biztonságosak. Ajánlott eljárás, hogy soha ne változtassunk állapotot GET-kérés során.
A CSRF-támadások a hitelesítéshez cookie-kat használó webalkalmazások ellen lehetségesek, mert:
- A böngészők egy webalkalmazás által kibocsátott cookie-kat tárolnak.
- A tárolt cookie-k munkamenet-cookie-kat tartalmaznak a hitelesített felhasználók számára.
- A böngészők minden, tartományhoz társított cookie-t elküldenek a webalkalmazásnak, függetlenül attól, hogy az alkalmazáskérés hogyan jött létre a böngészőben.
A CSRF-támadások azonban nem korlátozódnak a cookie-k kihasználására. Az alapszintű és a kivonatoló hitelesítés például sebezhető. Miután egy felhasználó bejelentkezett alapszintű vagy kivonatoló hitelesítéssel, a böngésző automatikusan elküldi a hitelesítő adatokat, amíg a munkamenet véget nem ér.
Ebben az összefüggésben munkamenet arra az ügyféloldali munkamenetre vonatkozik, amely során a felhasználó hitelesítése megtörtént. Nem kapcsolódik kiszolgálóoldali munkamenetekhez vagy ASP.NET Core Session Middleware.
A felhasználók óvintézkedéseket tehetnek a CSRF biztonsági rései ellen:
- Kijelentkezés a webalkalmazásból, ha befejezte a használatukat.
- A böngésző cookie-inak rendszeres törlése.
A CSRF biztonsági rései azonban alapvetően a webalkalmazással, nem pedig a végfelhasználóval kapcsolatos problémák.
A hitelesítés alapjai
Cookie-alapú hitelesítés a hitelesítés népszerű formája. A token alapú hitelesítési rendszerek egyre népszerűbbek, különösen az egyoldalas alkalmazások (SPA-k) esetében.
Cookie-alapú hitelesítés
Amikor egy felhasználó a saját felhasználónevével és jelszavával hitelesít, a rendszer egy jogkivonatot ad ki, amely tartalmaz egy hitelesítési jegyet, és ez felhasználható további hitelesítéshez és engedélyezéshez. A tokent egy cookie-ként tárolják, amelyet minden kérésnél az ügyféllel együtt küldenek. A cookie generálását és érvényesítését a Cookie Hitelesítési köztes szoftver végzi. A köztes szoftver egy felhasználónevet titkosított cookieszerializál. A következő kérések során a köztes szoftver ellenőrzi a cookie-t, újra létrehozza a főkomponenst, és hozzárendeli a főkomponenst a HttpContext.User tulajdonsághoz.
Tokenalapú hitelesítés
Ha egy felhasználó hitelesítése megtörtént, a rendszer tokent ad ki (nem pedig antiforgery tokent). A jogkivonat felhasználói adatokat tartalmaz jogcímek formájában, vagy egy hivatkozási jogkivonat formájában, amely az alkalmazást az alkalmazásban fenntartott felhasználói állapotra mutatja. Amikor egy felhasználó megpróbál hozzáférni egy hitelesítést igénylő erőforráshoz, a rendszer a jogkivonatot egy további engedélyezési fejléccel továbbítja az alkalmazásnak tulajdonosi jogkivonat formájában. Ez a megközelítés állapot nélkülivé teszi az alkalmazást. Minden további kérésben a jogkivonat továbbításra kerül a kiszolgálóoldali érvényesítéshez. Ez a jogkivonat nem titkosított; kódolt. A kiszolgálón a rendszer dekódolja a jogkivonatot, hogy hozzáférjen az adataihoz. A jogkivonat későbbi kérésekre való elküldéséhez tárolja a jogkivonatot a böngésző helyi tárolójában. Ne aggódjon a CSRF biztonsági rése miatt, ha a jogkivonat a böngésző helyi tárolójában van tárolva. A CSRF aggodalomra ad okot, ha a tokent egy cookie-ban tárolják. További információért lásd a GitHub probléma oldalt: az SPA kódminta két cookie-t ad hozzá.
Több, egy tartományban üzemeltetett alkalmazás
A megosztott üzemeltetési környezetek sebezhetők a munkamenet-eltérítés, a bejelentkezési CSRF és más támadások ellen.
Bár example1.contoso.net
és example2.contoso.net
különböző gazdagépek, implicit megbízhatósági kapcsolat áll fenn a *.contoso.net
tartománybeli gazdagépek között. Ez az implicit megbízhatósági kapcsolat lehetővé teszi, hogy a potenciálisan nem megbízható gazdagépek befolyásolják egymás cookie-jait (az AJAX-kéréseket szabályozó azonos eredetű szabályzatok nem feltétlenül vonatkoznak a HTTP-cookie-kra).
Az ugyanazon a tartományon üzemeltetett alkalmazások közötti megbízható cookie-kat kihasználó támadások megelőzhetők, ha nem osztanak meg tartományokat. Ha az egyes alkalmazásokat a saját tartományában üzemeltetik, nincs kihasználandó implicit cookie megbízhatósági kapcsolat.
ASP.NET Core antiforgery konfigurációja
Figyelmeztetés
ASP.NET Core a ASP.NET Core Data Protectionhasználatával implementálja a hamisítás elleni védelmet. Az adatvédelmi vermet úgy kell konfigurálni, hogy egy kiszolgálófarmban működjön. További információért lásd: Az adatvédelem konfigurálása.
Antiforgery middleware kerül be a függőség-injektálási tárolóba, ha az alábbi API-k egyikét meghívják Startup.ConfigureServices
:
A ASP.NET Core 2.0-s vagy újabb verzióiban a FormTagHelper injektálja az antiforgery tokeneket HTML-űrlapelemekbe. Egy Razor fájlban a következő korrektúra automatikusan létrehozza az antiforgery tokeneket:
<form method="post">
...
</form>
Hasonlóképpen, IHtmlHelper.BeginForm alapértelmezés szerint antiforgery tokeneket hoz létre, ha az űrlap metódusa nem GET.
A HTML-űrlapelemek antiforgery tokenjeinek automatikus létrehozása akkor történik, ha a <form>
címke tartalmazza a method="post"
attribútumot, és az alábbiak bármelyike igaz:
- A műveletattribútum üres (
action=""
). - A műveletattribútum nincs megadva (
<form method="post">
).
A HTML-űrlapelemekhez tartozó antiforgery tokenek automatikus létrehozása letiltható:
Explicit módon tiltsa le az antiforgery tokeneket a
asp-antiforgery
attribútummal:<form method="post" asp-antiforgery="false"> ... </form>
Az űrlapelem ki van zárva a Címkesegítők közül a Tag Helper ! opt-out szimbólumokhasználatával.
<!form method="post"> ... </!form>
Távolítsa el a
FormTagHelper
a nézetből. AFormTagHelper
eltávolítható egy nézetből az alábbi irányelv Razor nézethez való hozzáadásával:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Jegyzet
Razor lapok automatikusan védettek az XSRF/CSRF támadások ellen. További információ: XSRF/CSRF és Razor Pages.
A CSRF-támadások elleni védelem leggyakoribb módja a szinkronizáló jogkivonat-minta (STP) használata. Az STP akkor használatos, ha a felhasználó űrlapadatokat tartalmazó lapot kér:
- A kiszolgáló egy, az aktuális felhasználó identitásához társított jogkivonatot küld az ügyfélnek.
- Az ügyfél visszaküldi a jogkivonatot a kiszolgálónak ellenőrzés céljából.
- Ha a kiszolgáló olyan jogkivonatot kap, amely nem egyezik a hitelesített felhasználó identitásával, a rendszer elutasítja a kérést.
A token egyedi és kiszámíthatatlan. A jogkivonat arra is használható, hogy biztosítsa a kérelmek sorozatának megfelelő sorrendjét (például a következő kérelmek sorrendjének biztosításához: 1. oldal > 2. oldal > 3. oldal). Az összes ASP.NET Core MVC és Razor Pages sablonú űrlap valahogy antiforgery tokeneket hoz létre. A következő példanézet-páros antiforgery biztonsági tokeneket hoz létre:
<form asp-controller="Todo" asp-action="Create" method="post">
...
</form>
@using (Html.BeginForm("Create", "Todo"))
{
...
}
Kifejezetten adjon hozzá egy hamisítás elleni tokent egy <form>
elemhez a Tag Helper és a HTML-segéd használata nélkül @Html.AntiForgeryToken
.
<form action="/" method="post">
@Html.AntiForgeryToken()
</form>
Az előző esetekben ASP.NET Core az alábbi példához hasonló rejtett űrlapmezőt ad hozzá:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core három szűrőt tartalmaz, az antiforgery tokenek használatát:
Antiforgery beállítások
AntiforgeryOptions testreszabása a Startup.ConfigureServices
-en:
services.AddAntiforgery(options =>
{
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Állítsa be az antiforgery Cookie
tulajdonságokat a CookieBuilder osztály tulajdonságaival, ahogyan az az alábbi táblázatban látható.
Opció | Leírás |
---|---|
Cookie | Meghatározza az antiforgery cookie-k létrehozásához használt beállításokat. |
FormFieldName | Annak a rejtett űrlapmezőnek a neve, amelyet az antiforgery rendszer használ az antiforgery tokenek nézetekben való megjelenítéséhez. |
HeaderName | Az antiforgery rendszer által használt fejléc neve. Ha null , a rendszer csak az űrlapadatokat veszi figyelembe. |
SuppressXFrameOptionsHeader | Megadja, hogy el kívánja-e tiltani a X-Frame-Options fejléc generálását. Alapértelmezés szerint a fejléc "SAMEORIGIN" értékkel jön létre. Alapértelmezés szerint false . |
További információ: CookieAuthenticationOptions.
Antiforgery-funkciók konfigurálása az IAntiforgery használatával
IAntiforgery biztosítja az API-t az antiforgery funkciók konfigurálásához.
IAntiforgery
a Configure
osztály Startup
metódusában kérhető.
Az alábbi példában:
- Az alkalmazás kezdőlapján futó köztes szoftver egy antiforgery tokent hoz létre, és a válaszban cookie-ként küldi el.
- A kérés tokenje JavaScript-olvasható
-ként lesz elküldve, az alapértelmezett Angular elnevezési konvencióval, amint az az AngularJS szakaszban, le van írva.
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
}
Hamisítás elleni ellenőrzés megkövetelése
ValidateAntiForgeryToken egy műveletszűrő, amely egyéni műveletekre, vezérlőkre vagy globálisan alkalmazható. A szűrőt alkalmazó műveletekre irányuló kérések le lesznek tiltva, kivéve, ha a kérés érvényes antiforgery-jogkivonatot tartalmaz.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
{
ManageMessageId? message = ManageMessageId.Error;
var user = await GetCurrentUserAsync();
if (user != null)
{
var result =
await _userManager.RemoveLoginAsync(
user, account.LoginProvider, account.ProviderKey);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
message = ManageMessageId.RemoveLoginSuccess;
}
}
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
A ValidateAntiForgeryToken
attribútumhoz jogkivonatra van szükség az általa jelölt műveleti módszerekre irányuló kérelmekhez, beleértve a HTTP GET-kérelmeket is. Ha az alkalmazás vezérlőire a ValidateAntiForgeryToken
attribútum van alkalmazva, akkor a IgnoreAntiforgeryToken
attribútummal felülírható.
Jegyzet
ASP.NET Core nem támogatja az antiforgery tokenek automatikus hozzáadását a GET-kérelmekhez.
Az antiforgery tokenek automatikus ellenőrzése csak a nem biztonságos HTTP-metódusok esetén történik meg.
ASP.NET Core-alkalmazások nem hoznak létre antiforgery tokeneket a biztonságos HTTP-metódusokhoz (GET, HEAD, OPTIONS és TRACE). Ahelyett, hogy a ValidateAntiForgeryToken
attribútumot általánosan alkalmazná, majd felülírná IgnoreAntiforgeryToken
attribútumokkal, az AutoValidateAntiforgeryToken attribútum használható. Ez az attribútum ugyanúgy működik, mint a ValidateAntiForgeryToken
attribútum, azzal a különbségkel, hogy nem igényel jogkivonatokat a következő HTTP-metódusokkal végrehajtott kérelmekhez:
- SZEREZZ
- FEJ
- OPCIÓK
- NYOM
Javasoljuk a AutoValidateAntiforgeryToken
széles körű használatát nem API-szcenáriókhoz. Ez az attribútum biztosítja, hogy a POST-műveletek alapértelmezés szerint védettek legyenek. A másik lehetőség az, hogy alapértelmezés szerint figyelmen kívül hagyja az antiforgery tokeneket, kivéve, ha ValidateAntiForgeryToken
az egyes műveleti módszerekre van alkalmazva. Ebben a forgatókönyvben valószínűbb, hogy egy POST-műveletmetódus véletlenül védtelen marad, így az alkalmazás sebezhető lesz a CSRF-támadásokkal szemben. Minden POST-nak el kell küldenie a hamisítás elleni tokent.
Az API-k nem rendelkeznek automatikus mechanizmusokkal a jogkivonat nemcookie részének küldéséhez. A megvalósítás valószínűleg az ügyfélkód implementálásától függ. Néhány példa alább látható:
Osztályszintű példa:
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
Globális példa:
services.AddControllersWithViews(options =>
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
Globális vagy vezérlő antiforgery attribútumok felülbírálása
Az IgnoreAntiforgeryToken szűrővel kiküszöbölhető az adott művelethez (vagy vezérlőhöz) tartozó antiforgery token szükségessége. Alkalmazásakor ez a szűrő felülbírálja a magasabb szinten (globálisan vagy vezérlőn) megadott ValidateAntiForgeryToken
és AutoValidateAntiforgeryToken
szűrőket.
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
{
// no antiforgery token required
}
}
Jogkivonatok frissítése a hitelesítés után
A tokeneket a felhasználó hitelesítése után frissíteni kell úgy, hogy a felhasználót átirányítja egy felületre vagy Razor Pages oldalra.
JavaScript, AJAX és SLA-k
Hagyományos HTML-alapú alkalmazásokban rejtett űrlapmezőkön keresztül továbbítják az antiforgery jogkivonatokat a kiszolgálónak. A modern JavaScript-alapú alkalmazásokban és SLA-kban számos kérés programozott módon történik. Ezek az AJAX-kérések más technikákat (például kérésfejléceket vagy cookie-kat) is használhatnak a jogkivonat elküldéséhez.
Ha a cookie-kat hitelesítési jogkivonatok tárolására és API-kérések hitelesítésére használják a kiszolgálón, a CSRF potenciális probléma. Ha a helyi tárolót a jogkivonat tárolására használják, a CSRF biztonsági rése csökkenthető, mivel a rendszer nem küldi el automatikusan a helyi tárolóból származó értékeket a kiszolgálónak minden kéréssel együtt. A helyi tároló használata az antiforgery token ügyfélen való tárolására és a token kérésfejlécben történő elküldésére ajánlott módszer.
JavaScript
JavaScript nézetek használata esetén az azonosító egy szolgáltatás segítségével hozható létre a nézeten belül. Injektálja a IAntiforgery szolgáltatást a nézetbe, és hívja meg GetAndStoreTokens:
@{
ViewData["Title"] = "AJAX Demo";
}
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
<input type="hidden" id="RequestVerificationToken"
name="RequestVerificationToken" value="@GetAntiXsrfRequestToken()">
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<div class="row">
<p><input type="button" id="antiforgery" value="Antiforgery"></p>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == XMLHttpRequest.DONE) {
if (xhttp.status == 200) {
alert(xhttp.responseText);
} else {
alert('There was an error processing the AJAX request.');
}
}
};
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("antiforgery").onclick = function () {
xhttp.open('POST', '@Url.Action("Antiforgery", "Home")', true);
xhttp.setRequestHeader("RequestVerificationToken",
document.getElementById('RequestVerificationToken').value);
xhttp.send();
}
});
</script>
</div>
Ez a megközelítés szükségtelenné teszi a cookie-k szerverről történő közvetlen beállítását vagy kliensről való közvetlen olvasását.
Az előző példa JavaScript használatával olvassa be az AJAX POST fejléc rejtett mezőértékét.
A JavaScript a cookie-k jogkivonatait is elérheti, és a cookietartalmának használatával létrehozhat egy fejlécet a jogkivonat értékével.
context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken,
new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });
Feltételezve, hogy a szkript egy X-CSRF-TOKEN
nevű fejlécben kéri a jogkivonat küldését, konfigurálja úgy a hamisítás elleni szolgáltatást, hogy a X-CSRF-TOKEN
fejlécre keressen.
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
Az alábbi példa JavaScript használatával készít AJAX-kérést a megfelelő fejléccel:
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
var csrfToken = getCookie("CSRF-TOKEN");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status === 204) {
alert('Todo item is created successfully.');
} else {
alert('There was an error processing the AJAX request.');
}
}
};
xhttp.open('POST', '/api/items', true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.setRequestHeader("X-CSRF-TOKEN", csrfToken);
xhttp.send(JSON.stringify({ "name": "Learn C#" }));
AngularJS
Az AngularJS egy konvenciót használ a CSRF kezelésére. Ha a kiszolgáló cookie-t küld a XSRF-TOKEN
névvel, az AngularJS $http
szolgáltatás hozzáadja a cookie értéket egy fejléchez, amikor kérést küld a kiszolgálónak. Ez a folyamat automatikus. Az ügyfélnek nem kell explicit módon beállítania a fejlécet. A fejléc neve X-XSRF-TOKEN
. A kiszolgálónak észlelnie kell ezt a fejlécet, és ellenőriznie kell annak tartalmát.
Ahhoz, hogy ASP.NET Core API működjön ezzel a konvencióval az alkalmazás indításakor:
- Konfigurálja az alkalmazást úgy, hogy egy cookie nevű
XSRF-TOKEN
-ben adjon meg egy jogkivonatot. - Konfigurálja az antiforgery szolgáltatást egy
X-XSRF-TOKEN
nevű fejléc keresésére, amely az Angular alapértelmezett fejlécneve az XSRF-jogkivonat küldéséhez.
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
}
Jegyzet
Ha az antiforgery token mind a kérelem fejlécben, mind az űrlap hasznos adataiban szerepel, csak a fejlécben lévő token kerül érvényesítésre.
Windows-hitelesítés és hamisítást gátló sütik
A Windows-hitelesítés használatakor az alkalmazásvégpontokat ugyanúgy kell védeni a CSRF-támadások ellen, mint a cookie-k esetében. A böngésző implicit módon elküldi a hitelesítési környezetet a kiszolgálónak, ezért a végpontokat védeni kell a CSRF-támadások ellen.
Antiforgery kiterjesztése
A IAntiforgeryAdditionalDataProvider típus lehetővé teszi a fejlesztők számára a CSRF-ellenes rendszer viselkedésének kiterjesztését az egyes tokenekben történő további adatcserével. A GetAdditionalData metódust minden alkalommal meghívják, amikor létrehoz egy mezőt, és a visszatérési érték a létrehozott mezőben van beágyazva. A megvalósító visszaadhat egy időbélyeget, egy egyedi azonosítót vagy bármilyen más értéket, majd meghívhatja a ValidateAdditionalData függvényt, amikor a jogkivonat érvényesítésre kerül, hogy érvényesítse ezeket az adatokat. Az ügyfél felhasználóneve már be van ágyazva a létrehozott tokenekbe, így nincs szükség ezen információk külön feltüntetésére. Ha egy token kiegészítő adatokat tartalmaz, de nincs konfigurálva IAntiForgeryAdditionalDataProvider
, akkor a kiegészítő adatokat nem érvényesítik.