ASP.NET Core 공격 방지 교차 사이트 요청 위조 XSRF/CSRF)Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core

Steve Smith, Fiyaz Hasan, 및 Rick AndersonBy Steve Smith, Fiyaz Hasan, and Rick Anderson

교차 사이트 요청 위조 (XSRF 또는 CSRF, 발음 함 참조 surf)가 악의적인 웹 앱 클라이언트 브라우저와를 신뢰 하는 웹 응용 프로그램 간의 상호 작용 영향을 줄 수는 그에 따라 웹 호스팅 응용 프로그램에 대 한 공격 브라우저.Cross-site request forgery (also known as XSRF or CSRF, pronounced see-surf) is an attack against web-hosted apps whereby a malicious web app can influence the interaction between a client browser and a web app that trusts that browser. 이러한 공격은 웹 브라우저가 웹 사이트에 일부 유형의 인증 토큰 모든 요청에 자동으로 전송 하기 때문에 가능 합니다.These attacks are possible because web browsers send some types of authentication tokens automatically with every request to a website. 이러한 형태의 악용은 라고도 원클릭 공격 또는 세션 도용을 사용자 세션의 이전에 인증 활용 하기 때문에 방지할 수 있었던 공격입니다.This form of exploit is also known as a one-click attack or session riding because the attack takes advantage of the user's previously authenticated session.

CSRF 공격의 예:An example of a CSRF attack:

  1. 사용자가에 로그인 할 www.good-banking-site.com 폼 인증을 사용 하 여 합니다.A user signs into www.good-banking-site.com using forms authentication. 서버에서 사용자를 인증 하지 않으며 인증 쿠키를 포함 하는 응답 합니다.The server authenticates the user and issues a response that includes an authentication cookie. 사이트는 유효한 인증 쿠키와 함께 수신 하는 모든 요청을 신뢰 하기 때문에 공격에 취약 합니다.The site is vulnerable to attack because it trusts any request that it receives with a valid authentication cookie.

  2. 사용자가 악성 사이트를 방문 www.bad-crook-site.com합니다.The user visits a malicious site, www.bad-crook-site.com.

    악성 사이트 www.bad-crook-site.com, 다음과 유사한 HTML 폼을 포함 합니다.The malicious site, www.bad-crook-site.com, contains an HTML form similar to the following:

    <h1>Congratulations! You're a Winner!</h1>
    <form action="http://good-banking-site.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>
    

    양식의 action 악성 사이트 아닌 취약 한 사이트에 대 한 게시 합니다.Notice that the form's action posts to the vulnerable site, not to the malicious site. CSRF의 "사이트 간" 부분입니다.This is the "cross-site" part of CSRF.

  3. 제출 단추를 선택합니다.The user selects the submit button. 브라우저 요청을 수행 하 고 요청 된 도메인에 대 한 인증 쿠키를 자동으로 포함 www.good-banking-site.com합니다.The browser makes the request and automatically includes the authentication cookie for the requested domain, www.good-banking-site.com.

  4. 요청에서 실행 되는 www.good-banking-site.com 사용자의 인증 컨텍스트를 사용 하는 서버 인증된 된 사용자가을 수행할 수 있는 모든 작업을 수행할 수 있습니다.The request runs on the www.good-banking-site.com server with the user's authentication context and can perform any action that an authenticated user is allowed to perform.

사용자가 양식을 전송 하는 단추를 선택 하는 시나리오 뿐 아니라 악성 사이트는 다음을 수행할 수 있습니다.In addition to the scenario where the user selects the button to submit the form, the malicious site could:

  • 폼을 자동으로 전송 하는 스크립트를 실행 합니다.Run a script that automatically submits the form.
  • 양식 전송이 AJAX 요청으로 보냅니다.Send the form submission as an AJAX request.
  • CSS를 사용 하 여 폼을 숨깁니다.Hide the form using CSS.

이러한 다양 한 시나리오는 모든 작업 또는 처음 악성 사이트를 방문 이외의 사용자의 입력에 필요 하지 않습니다.These alternative scenarios don't require any action or input from the user other than initially visiting the malicious site.

HTTPS를 사용 하 여 CSRF 공격을 방지 하지 않습니다.Using HTTPS doesn't prevent a CSRF attack. 악성 사이트로 보낼 수는 https://www.good-banking-site.com/ 안전 하지 않은 요청을 보낼 수 처럼 손쉽게 요청 합니다.The malicious site can send an https://www.good-banking-site.com/ request just as easily as it can send an insecure request.

일부 공격 대상 작업을 수행 하려면 이미지 태그를 사용할 수는 쿼리에서 GET 요청에 응답 하는 끝점입니다.Some attacks target endpoints that respond to GET requests, in which case an image tag can be used to perform the action. 이 형태의 공격이 이미지를 허용 하지만 JavaScript를 차단 하는 포럼 사이트에서 일반적입니다.This form of attack is common on forum sites that permit images but block JavaScript. 변수 또는 리소스 변경에 GET 요청에서 상태를 변경 하는 앱은 악의적인 공격에 취약 합니다.Apps that change state on GET requests, where variables or resources are altered, are vulnerable to malicious attacks. 상태를 변경 하는 GET 요청은 안전 하지 않습니다. GET 요청에서 상태 변경 하는 것이 좋습니다.GET requests that change state are insecure. A best practice is to never change state on a GET request.

CSRF 공격 되므로 인증용 쿠키를 사용 하는 웹 응용 프로그램에 대해 발생할 수 있습니다.CSRF attacks are possible against web apps that use cookies for authentication because:

  • 브라우저 웹 응용 프로그램에서 발급 하는 쿠키를 저장 합니다.Browsers store cookies issued by a web app.
  • 저장 된 쿠키는 인증 된 사용자에 대 한 세션 쿠키를 포함합니다.Stored cookies include session cookies for authenticated users.
  • 브라우저가 모든 쿠키와 관련 된 도메인을 웹 응용 프로그램 브라우저 내에서 응용 프로그램에 요청 생성 방법에 관계 없이 모든 요청을 전송 합니다.Browsers send all of the cookies associated with a domain to the web app every request regardless of how the request to app was generated within the browser.

그러나 CSRF 공격에 제한 되지 않습니다 쿠키를 이용 합니다.However, CSRF attacks aren't limited to exploiting cookies. 예를 들어, 기본 및 다이제스트 인증 취약 됩니다.For example, Basic and Digest authentication are also vulnerable. 브라우저에서 세션까지 자격 증명을 자동으로 전송 후 사용자가 기본 또는 다이제스트 인증 로그인을† 종료 합니다.After a user signs in with Basic or Digest authentication, the browser automatically sends the credentials until the session† ends.

†이 컨텍스트에서 세션 참조 하는 사용자가 인증 하는 클라이언트 세션입니다.†In this context, session refers to the client-side session during which the user is authenticated. 서버 쪽 세션에 관련 되지 않은 또는 ASP.NET Core 세션 미들웨어합니다.It's unrelated to server-side sessions or ASP.NET Core Session Middleware.

사용자가 예방 조치를 수행 하 여 CSRF 취약점을 방지할 수 있습니다.Users can guard against CSRF vulnerabilities by taking precautions:

  • 사용 하 여 완료 되 면 웹 앱에서 로그인 합니다.Sign off of web apps when finished using them.
  • 주기적으로 지우기 브라우저 쿠키입니다.Clear browser cookies periodically.

그러나 CSRF 취약점은 기본적으로 웹 앱을 최종 사용자가 아닌 문제입니다.However, CSRF vulnerabilities are fundamentally a problem with the web app, not the end user.

인증 기본 사항Authentication fundamentals

쿠키 기반 인증에는 인기 있는 형태의 인증입니다.Cookie-based authentication is a popular form of authentication. 토큰 기반 인증 시스템은 단일 페이지 응용 프로그램 (SPAs)를 위해 특별히에서 인기, 커지고 있습니다.Token-based authentication systems are growing in popularity, especially for Single Page Applications (SPAs).

사용자가 자신의 사용자 이름과 암호를 사용 하 여 인증, 인증 및 권한 부여에 사용할 수 있는 인증 티켓을 포함 하는 토큰을 발급 하는 합니다.When a user authenticates using their username and password, they're issued a token, containing an authentication ticket that can be used for authentication and authorization. 토큰이는 클라이언트는 모든 요청을 함께 제공 되는 쿠키 함에 따라 저장 됩니다.The token is stored as a cookie that accompanies every request the client makes. 생성 하 고이 쿠키를 유효성 검사 쿠키 인증 미들웨어에서 수행 됩니다.Generating and validating this cookie is performed by the Cookie Authentication Middleware. 미들웨어 사용자 계정 암호화 된 쿠키에 serialize 합니다.The middleware serializes a user principal into an encrypted cookie. 이후 요청에서 미들웨어 쿠키의 유효성을 검사, 주 서버를 다시 만드는 및 보안 주체에 할당 된 사용자 속성 HttpContext합니다.On subsequent requests, the middleware validates the cookie, recreates the principal, and assigns the principal to the User property of HttpContext.

토큰 기반 인증Token-based authentication

사용자가 인증 될 때 (하지 antiforgery 토큰) 토큰을 발급 하는 합니다.When a user is authenticated, they're issued a token (not an antiforgery token). 형식으로 사용자 정보를 포함 하는 토큰 클레임 또는 응용 프로그램에서 유지 관리 하는 사용자 상태를 응용 프로그램을 가리키는 참조 토큰입니다.The token contains user information in the form of claims or a reference token that points the app to user state maintained in the app. 사용자가 인증을 요구 하는 리소스에 액세스 하려고 하는 경우 응용 프로그램을 추가 인증 헤더에서 전달자 토큰의 형태로 토큰이 보내집니다.When a user attempts to access a resource requiring authentication, the token is sent to the app with an additional authorization header in form of Bearer token. 이렇게 하면 응용 프로그램 상태 비저장 있습니다.This makes the app stateless. 각 후속 요청에 토큰은 서버 쪽 유효성 검사에 대 한 요청에 전달 됩니다.In each subsequent request, the token is passed in the request for server-side validation. 이 토큰이 없는 암호화 된; 있기 인코딩된합니다.This token isn't encrypted; it's encoded. 서버에서 해당 정보에 액세스 하는 토큰은 디코딩됩니다.On the server, the token is decoded to access its information. 토큰 이후의 요청을 보내려면 토큰 브라우저의 로컬 저장소에 저장 합니다.To send the token on subsequent requests, store the token in the browser's local storage. 토큰은 브라우저의 로컬 저장소에 저장 되는 경우 CSRF 취약점에 대 한 관심이 해서는 안 됩니다.Don't be concerned about CSRF vulnerability if the token is stored in the browser's local storage. CSRF 문제가 있으면 토큰 쿠키에 저장 됩니다.CSRF is a concern when the token is stored in a cookie.

한 도메인에서 호스팅되는 여러 앱Multiple apps hosted at one domain

공유 호스팅 환경은 세션 하이재킹, CSRF, 로그인 및 기타 공격에 취약 합니다.Shared hosting environments are vulnerable to session hijacking, login CSRF, and other attacks.

하지만 example1.contoso.netexample2.contoso.net 는 서로 다른 호스트에서 호스트 간의 암시적 트러스트 관계가 있는 *.contoso.net 도메인입니다.Although example1.contoso.net and example2.contoso.net are different hosts, there's an implicit trust relationship between hosts under the *.contoso.net domain. 이 암시적 트러스트 관계에는 신뢰할 수 없는 호스트를 (AJAX 요청을 제어 하는 동일 원본 정책 반드시 HTTP 쿠키를 적용 하지 않는) 다른 사용자의 쿠키에 영향을 줄 수 있습니다.This implicit trust relationship allows potentially untrusted hosts to affect each other's cookies (the same-origin policies that govern AJAX requests don't necessarily apply to HTTP cookies).

도메인을 공유 하지 않고 함으로써 같은 도메인에 호스트 되는 앱 간에 신뢰할 수 있는 쿠키를 악용 하는 공격을 방지할 수 있습니다.Attacks that exploit trusted cookies between apps hosted on the same domain can be prevented by not sharing domains. 각 응용 프로그램은 자체 도메인에서 호스트 되는 경우 암시적 쿠키 트러스트 관계가 없는 악용할 수 있습니다.When each app is hosted on its own domain, there is no implicit cookie trust relationship to exploit.

ASP.NET Core antiforgery 구성ASP.NET Core antiforgery configuration

경고

ASP.NET Core antiforgery를 사용 하 여 구현 ASP.NET Core 데이터 보호합니다.ASP.NET Core implements antiforgery using ASP.NET Core Data Protection. 데이터 보호 스택의 서버 팜에서 작동 하도록 구성 되어야 합니다.The data protection stack must be configured to work in a server farm. 참조 데이터 보호를 구성 자세한 정보에 대 한 합니다.See Configuring data protection for more information.

ASP.NET Core 2.0 이상에서는 FormTagHelper antiforgery 토큰 HTML 폼 요소를 삽입 합니다.In ASP.NET Core 2.0 or later, the FormTagHelper injects antiforgery tokens into HTML form elements. Razor 파일에 다음 태그는 자동으로 antiforgery 토큰을 생성 합니다.The following markup in a Razor file automatically generates antiforgery tokens:

<form method="post">
    ...
</form>

마찬가지로, IHtmlHelper.BeginForm 폼의 메서드가 GET 실행 되지 않으면 기본적으로 antiforgery 토큰을 생성 합니다.Similarily, IHtmlHelper.BeginForm generates antiforgery tokens by default if the form's method isn't GET.

발생 하는 HTML 폼 요소에 대 한 자동 생성 antiforgery 토큰의 경우는 <form> 태그에는 method="post" 특성 및 다음 중 하나에 해당할:The automatic generation of antiforgery tokens for HTML form elements happens when the <form> tag contains the method="post" attribute and either of the following are true:

  • 동작 특성이 비어 (action="").The action attribute is empty (action="").
  • 작업 특성을 제공 하지 않으면 (<form method="post">).The action attribute isn't supplied (<form method="post">).

HTML 폼 요소에 대 한 antiforgery 토큰의 자동 생성을 비활성화할 수 있습니다.Automatic generation of antiforgery tokens for HTML form elements can be disabled:

  • Antiforgery 토큰을 사용 하 여 명시적으로 비활성화할는 asp-antiforgery 특성:Explicitly disable antiforgery tokens with the asp-antiforgery attribute:

    <form method="post" asp-antiforgery="false">
        ...
    </form>
    
  • Form 요소는 선택한 아웃 태그 도우미의 태그 도우미를 사용 하 여 ! 옵트아웃 기호:The form element is opted-out of Tag Helpers by using the Tag Helper ! opt-out symbol:

    <!form method="post">
        ...
    </!form>
    
  • 제거는 FormTagHelper 보기에서 합니다.Remove the FormTagHelper from the view. FormTagHelper Razor 보기에는 다음 지시문을 추가 하 여 보기에서 제거할 수 있습니다.The FormTagHelper can be removed from a view by adding the following directive to the Razor view:

    @removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
    

참고

Razor 페이지 XSRF/CSRF에서 자동으로 보호 됩니다.Razor Pages are automatically protected from XSRF/CSRF. 자세한 내용은 참조 XSRF/CSRF 및 Razor 페이지합니다.For more information, see XSRF/CSRF and Razor Pages.

가장 일반적인 방법은 CSRF 공격 으로부터 보호 하는 데 사용 하는 것은 동기화 장치 토큰 패턴이 (STP).The most common approach to defending against CSRF attacks is to use the Synchronizer Token Pattern (STP). STP은 사용자 양식 데이터로 페이지를 요청할 때 사용 됩니다.STP is used when the user requests a page with form data:

  1. 서버는 클라이언트에 현재 사용자의 id와 연결 된 토큰을 보냅니다.The server sends a token associated with the current user's identity to the client.
  2. 클라이언트가 보냅니다 확인을 위해 서버를 다시 토큰.The client sends back the token to the server for verification.
  3. 인증 된 사용자의 id와 일치 하지 않는 토큰을 수신 하는 서버, 요청이 거부 됩니다.If the server receives a token that doesn't match the authenticated user's identity, the request is rejected.

토큰이 고유 하 고 예측할 수 없는 되었습니다.The token is unique and unpredictable. 토큰을 사용 하 여 일련의 요청을 적절 한 시퀀싱 할 수도 수 (요청 시퀀스의 예를 들어 보장: 1 페이지가 – 2 페이지 – 3 페이지).The token can also be used to ensure proper sequencing of a series of requests (for example, ensuring the request sequence of: page 1 – page 2 – page 3). 모든 Razor 페이지 및 ASP.NET Core MVC 템플릿에서 양식의 antiforgery 토큰을 생성 합니다.All of the forms in ASP.NET Core MVC and Razor Pages templates generate antiforgery tokens. 다음 예제 보기 쌍 antiforgery 토큰을 생성 합니다.The following pair of view examples generate antiforgery tokens:

<form asp-controller="Manage" asp-action="ChangePassword" method="post">
    ...
</form>

@using (Html.BeginForm("ChangePassword", "Manage"))
{
    ...
}

Antiforgery 토큰을 명시적으로 추가 된 <form> HTML 도우미와 태그 도우미를 사용 하지 않고 요소 @Html.AntiForgeryToken :Explicitly add an antiforgery token to a <form> element without using Tag Helpers with the HTML helper @Html.AntiForgeryToken:

<form action="/" method="post">
    @Html.AntiForgeryToken()
</form>

위의 경우 중 각 ASP.NET Core 다음과 유사한 숨겨진된 양식 필드를 추가합니다.In each of the preceding cases, ASP.NET Core adds a hidden form field similar to the following:

<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">

ASP.NET Core 3 개 포함 필터 antiforgery 토큰을 사용 하기 위한:ASP.NET Core includes three filters for working with antiforgery tokens:

Antiforgery 옵션Antiforgery options

사용자 지정 antiforgery 옵션Startup.ConfigureServices:Customize antiforgery options in Startup.ConfigureServices:

services.AddAntiforgery(options => 
{
    options.CookieDomain = "contoso.com";
    options.CookieName = "X-CSRF-TOKEN-COOKIENAME";
    options.CookiePath = "Path";
    options.FormFieldName = "AntiforgeryFieldname";
    options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
    options.RequireSsl = false;
    options.SuppressXFrameOptionsHeader = false;
});
옵션Option 설명Description
쿠키Cookie Antiforgery 쿠키를 만드는 데 설정을 결정 합니다.Determines the settings used to create the antiforgery cookies.
CookieDomainCookieDomain 쿠키의 도메인입니다.The domain of the cookie. 기본값은 null입니다.Defaults to null. 이 속성은 사용 되지 않으며 이후 버전에서 제거 됩니다.This property is obsolete and will be removed in a future version. 권장 방법은 Cookie.Domain입니다.The recommended alternative is Cookie.Domain.
CookieNameCookieName 쿠키의 이름입니다.The name of the cookie. 을 설정 하지 시스템 생성 고유 이름으로 시작 된 DefaultCookiePrefix (". AspNetCore.Antiforgery입니다. ")입니다.If not set, the system generates a unique name beginning with the DefaultCookiePrefix (".AspNetCore.Antiforgery."). 이 속성은 사용 되지 않으며 이후 버전에서 제거 됩니다.This property is obsolete and will be removed in a future version. 권장 방법은 Cookie.Name입니다.The recommended alternative is Cookie.Name.
CookiePathCookiePath 쿠키에 설정 된 경로입니다.The path set on the cookie. 이 속성은 사용 되지 않으며 이후 버전에서 제거 됩니다.This property is obsolete and will be removed in a future version. 권장 방법은 Cookie.Path입니다.The recommended alternative is Cookie.Path.
FormFieldNameFormFieldName 뷰에서 antiforgery 토큰을 렌더링 하는 antiforgery 시스템에서 사용 하는 숨겨진된 폼 필드의 이름입니다.The name of the hidden form field used by the antiforgery system to render antiforgery tokens in views.
HeaderNameHeaderName Antiforgery 시스템에서 사용 하는 헤더의 이름입니다.The name of the header used by the antiforgery system. 경우 null, 시스템에서는 양식 데이터입니다.If null, the system considers only form data.
RequireSslRequireSsl Antiforgery 시스템에서 SSL이 필요한 지 여부를 지정 합니다.Specifies whether SSL is required by the antiforgery system. 경우 true, 비 SSL 요청이 실패 합니다.If true, non-SSL requests fail. 기본값은 false입니다.Defaults to false. 이 속성은 사용 되지 않으며 이후 버전에서 제거 됩니다.This property is obsolete and will be removed in a future version. 메서드 대신 Cookie.SecurePolicy를 설정 하는 것입니다.The recommended alternative is to set Cookie.SecurePolicy.
SuppressXFrameOptionsHeaderSuppressXFrameOptionsHeader 생성을 표시 하지 않을 것인지를 지정 된 X-Frame-Options 헤더입니다.Specifies whether to suppress generation of the X-Frame-Options header. 기본적으로 머리글은 "SAMEORIGIN"의 값으로 생성 됩니다.By default, the header is generated with a value of "SAMEORIGIN". 기본값은 false입니다.Defaults to false.

자세한 내용은 참조 CookieAuthenticationOptions합니다.For more information, see CookieAuthenticationOptions.

IAntiforgery와 antiforgery 기능을 구성 합니다.Configure antiforgery features with IAntiforgery

IAntiforgery antiforgery 기능을 구성 하는 API를 제공 합니다.IAntiforgery provides the API to configure antiforgery features. IAntiforgery 요청한 크기에 Configure 의 메서드는 Startup 클래스입니다.IAntiforgery can be requested in the Configure method of the Startup class. 다음 예제에서는 응용 프로그램의 홈 페이지에서 미들웨어를 사용 하 여 antiforgery 토큰을 생성 하 고 쿠키 (사용 하 여 기본 각도 명명 규칙이이 항목의 뒷부분에서 설명)으로 응답에 보냅니다.The following example uses middleware from the app's home page to generate an antiforgery token and send it in the response as a cookie (using the default Angular naming convention described later in this topic):

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))
        {
            // The request token can be sent as a JavaScript-readable cookie, 
            // and Angular uses it by default.
            var tokens = antiforgery.GetAndStoreTokens(context);
            context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, 
                new CookieOptions() { HttpOnly = false });
        }

        return next(context);
    });
}

Antiforgery 유효성 검사 필요Require antiforgery validation

ValidateAntiForgeryToken 는 개별 작업은 컨트롤러에 적용할 수 있는 작업 필터는 전역적으로 또는 합니다.ValidateAntiForgeryToken is an action filter that can be applied to an individual action, a controller, or globally. 요청에 유효한 antiforgery 토큰에 포함 되지 않으면이 필터 적용이 영향을 주는 작업에 대 한 요청 차단 됩니다.Requests made to actions that have this filter applied are blocked unless the request includes a valid antiforgery token.

[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 });
}

ValidateAntiForgeryToken 특성에 대 한 요청 작업 메서드 HTTP GET 요청을 포함 하 여 데코레이팅되 토큰이 필요 합니다.The ValidateAntiForgeryToken attribute requires a token for requests to the action methods it decorates, including HTTP GET requests. 경우는 ValidateAntiForgeryToken 특성은 응용 프로그램의 컨트롤러에 적용 되며,으로 재정의 될 수는 IgnoreAntiforgeryToken 특성입니다.If the ValidateAntiForgeryToken attribute is applied across the app's controllers, it can be overridden with the IgnoreAntiforgeryToken attribute.

참고

ASP.NET Core GET 요청에 antiforgery 토큰을 자동으로 추가 지원 하지 않습니다.ASP.NET Core doesn't support adding antiforgery tokens to GET requests automatically.

자동으로 안전 하지 않은 HTTP 메서드에 대 한 antiforgery 토큰 유효성을 검사합니다Automatically validate antiforgery tokens for unsafe HTTP methods only

ASP.NET Core 응용 프로그램 안전 HTTP 메서드 (GET, HEAD, 옵션 및 추적)에 대 한 antiforgery 토큰을 생성 하지 않습니다.ASP.NET Core apps don't generate antiforgery tokens for safe HTTP methods (GET, HEAD, OPTIONS, and TRACE). 광범위 하 게 적용 하는 대신는 ValidateAntiForgeryToken 특성 및 사용 하 여를 재정의 IgnoreAntiforgeryToken 특성은 AutoValidateAntiforgeryToken 특성을 사용할 수 있습니다.Instead of broadly applying the ValidateAntiForgeryToken attribute and then overriding it with IgnoreAntiforgeryToken attributes, the AutoValidateAntiforgeryToken attribute can be used. 이 특성은 동일 하 게 작동는 ValidateAntiForgeryToken 특성을 제외 하 고 토큰에 대 한 다음과 같은 HTTP 메서드를 사용 하 여 요청 필요 하지 않습니다.This attribute works identically to the ValidateAntiForgeryToken attribute, except that it doesn't require tokens for requests made using the following HTTP methods:

  • 가져오기GET
  • HEADHEAD
  • 옵션OPTIONS
  • TRACETRACE

사용 권장 AutoValidateAntiforgeryToken 비 API 시나리오에 대 한 광범위 하 게 합니다.We recommend use of AutoValidateAntiforgeryToken broadly for non-API scenarios. 이렇게 하면 기본적으로 POST 작업 보호 됩니다.This ensures POST actions are protected by default. 대신 사용 하는 표시 되지 않으면 기본적으로 antiforgery 토큰을 무시 하도록 ValidateAntiForgeryToken 개별 작업 메서드에 적용 됩니다.The alternative is to ignore antiforgery tokens by default, unless ValidateAntiForgeryToken is applied to individual action methods. 것에 쓰지만 대개 남겨둘 POST 작업 메서드에 대 한이 시나리오에서는 보호 되지 않은 상태로 실수로 CSRF 공격에 취약 한 응용 프로그램을 종료 합니다.It's more likely in this scenario for a POST action method to be left unprotected by mistake, leaving the app vulnerable to CSRF attacks. 모든 게시물 antiforgery 토큰을 보내야 합니다.All POSTs should send the antiforgery token.

Api는 토큰의 쿠키 일부로 보내기 위한 자동 메커니즘이 필요는 없습니다.APIs don't have an automatic mechanism for sending the non-cookie part of the token. 아마도 구현 클라이언트 코드 구현에 따라 달라 집니다.The implementation probably depends on the client code implementation. 몇 가지 예는 다음과 같습니다.Some examples are shown below:

클래스 수준 예:Class-level example:

[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{

전역 예:Global example:

services.AddMvc(options => 
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));

전역 재정의 또는 컨트롤러 antiforgery 특성Override global or controller antiforgery attributes

IgnoreAntiforgeryToken 필터는 지정 된 작업 (또는 컨트롤러)에 대 한 antiforgery 토큰에 대 한 필요성을 제거 하는 데 사용 됩니다.The IgnoreAntiforgeryToken filter is used to eliminate the need for an antiforgery token for a given action (or controller). 이 필터 재정의 적용 하면 ValidateAntiForgeryTokenAutoValidateAntiforgeryToken (전역적으로 또는 컨트롤러)는 더 높은 수준에서 지정 된 필터입니다.When applied, this filter overrides ValidateAntiForgeryToken and AutoValidateAntiforgeryToken filters specified at a higher level (globally or on a controller).

[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
    [HttpPost]
    [IgnoreAntiforgeryToken]
    public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
    {
        // no antiforgery token required
    }
}

인증 후 새로 고침 토큰Refresh tokens after authentication

뷰 또는 Razor 페이지의 페이지에 사용자를 리디렉션하여 사용자가 인증 한 후 토큰 새로 고쳐야 합니다.Tokens should be refreshed after the user is authenticated by redirecting the user to a view or Razor Pages page.

JavaScript, AJAX 및 SPAsJavaScript, AJAX, and SPAs

기존 HTML 기반 앱에서 antiforgery 토큰 숨겨진된 양식 필드를 사용 하 여 서버에 전달 됩니다.In traditional HTML-based apps, antiforgery tokens are passed to the server using hidden form fields. 최신 JavaScript 기반 응용 프로그램 및 SPAs 많은 요청이 프로그래밍 방식으로 이루어집니다.In modern JavaScript-based apps and SPAs, many requests are made programmatically. 이러한 AJAX 요청 토큰 다른 기술 (예: 요청 헤더 또는 쿠키)를 사용할 수 있습니다.These AJAX requests may use other techniques (such as request headers or cookies) to send the token.

인증 토큰을 저장 하 고 서버에 대 한 API 요청을 인증 쿠키를 사용 하는 경우 CSRF 잠재적인 문제가 됩니다.If cookies are used to store authentication tokens and to authenticate API requests on the server, CSRF is a potential problem. 토큰을 저장할 로컬 저장소 사용 하는 경우 로컬 저장소에서 값은 모든 요청을 사용 하 여 서버에 자동으로 전송 되지 않습니다 때문에 CSRF 취약성을 완화할 수 있습니다.If local storage is used to store the token, CSRF vulnerability might be mitigated because values from local storage aren't sent automatically to the server with every request. 따라서 요청 헤더는 권장된 방법으로 토큰을 보내는 클라이언트에 antiforgery 토큰을 저장할 로컬 저장소를 사용 합니다.Thus, using local storage to store the antiforgery token on the client and sending the token as a request header is a recommended approach.

JavaScriptJavaScript

JavaScript에서 뷰를 사용 하는 토큰 만들 수 있습니다 보기 내에서 서비스를 사용 하 여 합니다.Using JavaScript with views, the token can be created using a service from within the view. 삽입 된 Microsoft.AspNetCore.Antiforgery.IAntiforgery 보기 및 호출 계층에 서비스 GetAndStoreTokens:Inject the Microsoft.AspNetCore.Antiforgery.IAntiforgery service into the view and call 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>

이 방법은 서버에서 쿠키를 설정 하거나 클라이언트에서 읽기를 직접 사용 않아도 됩니다.This approach eliminates the need to deal directly with setting cookies from the server or reading them from the client.

앞의 예제 JavaScript를 사용 하 여 AJAX POST 헤더에 대 한 숨겨진된 필드 값을 읽을 수 있습니다.The preceding example uses JavaScript to read the hidden field value for the AJAX POST header.

JavaScript 쿠키의 토큰에 액세스할 수 있고 쿠키의 콘텐츠를 사용 하 여 토큰의 값을 사용 하는 헤더를 만듭니다.JavaScript can also access tokens in cookies and use the cookie's contents to create a header with the token's value.

context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken, 
    new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });

헤더에 토큰을 보낼 요청 스크립트 가정 X-CSRF-TOKEN, 찾으려는 antiforgery 서비스 구성의 X-CSRF-TOKEN 헤더:Assuming the script requests to send the token in a header called X-CSRF-TOKEN, configure the antiforgery service to look for the X-CSRF-TOKEN header:

services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");

다음 예제에서는 JavaScript를 사용 하 여 적절 한 헤더를 사용 하는 AJAX 요청 확인.The following example uses JavaScript to make an AJAX request with the appropriate header:

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 == 200) {
            alert(xhttp.responseText);
        } else {
            alert('There was an error processing the AJAX request.');
        }
    }
};
xhttp.open('POST', '/api/password/changepassword', true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.setRequestHeader("X-CSRF-TOKEN", csrfToken);
xhttp.send(JSON.stringify({ "newPassword": "ReallySecurePassword999$$$" }));

AngularJSAngularJS

AngularJS는 CSRF 주소로 규칙을 사용합니다.AngularJS uses a convention to address CSRF. 서버 이름으로 쿠키를 전송 하는 경우 XSRF-TOKEN, AngularJS $http 서비스 서버에 요청을 보낼 때 헤더에 쿠키 값을 추가 합니다.If the server sends a cookie with the name XSRF-TOKEN, the AngularJS $http service adds the cookie value to a header when it sends a request to the server. 이 프로세스는 자동.This process is automatic. 헤더를 명시적으로 설정할 필요가 없습니다.The header doesn't need to be set explicitly. 헤더 이름이 X-XSRF-TOKEN합니다.The header name is X-XSRF-TOKEN. 서버는이 헤더를 검색 하 고 해당 내용의 유효성을 검사 해야 합니다.The server should detect this header and validate its contents.

ASP.NET Core API에 대 한이 규칙을 통해 작동 합니다.For ASP.NET Core API work with this convention:

  • 호출 하는 쿠키에 토큰을 제공할 앱을 구성 XSRF-TOKEN합니다.Configure your app to provide a token in a cookie called XSRF-TOKEN.
  • 라는 헤더 찾으려는 antiforgery 서비스 구성 X-XSRF-TOKEN합니다.Configure the antiforgery service to look for a header named X-XSRF-TOKEN.
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

예제 코드 살펴보기 및 다운로드(다운로드 방법)View or download sample code (how to download)

Antiforgery 확장Extend antiforgery

IAntiForgeryAdditionalDataProvider 형식에서는 개발자가 각 토큰의 추가 데이터를 왕복 하 여 앤티 CSRF 시스템의 동작을 확장할 수 있습니다.The IAntiForgeryAdditionalDataProvider type allows developers to extend the behavior of the anti-CSRF system by round-tripping additional data in each token. GetAdditionalData 될 때마다 메서드는 필드 토큰이 생성 되 고 반환 값은 생성 되는 토큰 내에 포함 되어 있습니다.The GetAdditionalData method is called each time a field token is generated, and the return value is embedded within the generated token. 구현 자가 수 타임 스탬프, nonce, 또는 다른 모든 값을 반환 하 고 호출 ValidateAdditionalData 토큰의 유효성을 검사할 때이 데이터를 유효성 검사 합니다.An implementer could return a timestamp, a nonce, or any other value and then call ValidateAdditionalData to validate this data when the token is validated. 클라이언트의 사용자 이름은 이미 생성 된 토큰에 포함 되어 있으므로이 정보를 포함할 필요가 없습니다.The client's username is already embedded in the generated tokens, so there's no need to include this information. 아니지만 추가 데이터 토큰을 포함 하는 경우 IAntiForgeryAdditionalDataProvider 가 구성, 보조 데이터 확인 되지 않습니다.If a token includes supplemental data but no IAntiForgeryAdditionalDataProvider is configured, the supplemental data isn't validated.

추가 자료Additional resources