ASP.NET MVC는 웹 애플리케이션에서 크로스사이트 요청 위조(CSRF) 공격을 방지하기 위해 Html.AntiForgeryToken() 메서드를 제공합니다. 이 기능은 사용자 인증 상태를 악용하는 공격을 차단하며, 단순히 스크립트 삽입을 이용하는 XSS와는 목적과 방식이 다릅니다.
기본 문제 상황
예를 들어, 홈페이지에 공지를 입력하는 폼이 있다고 가정합시다. 기본적인 구현은 다음과 같습니다:
@using (Html.BeginForm("Text", "Home", FormMethod.Post))
{
@:공지사항: <input type="text" name="Notice" id="Notice" />
<input type="submit" value="전송" />
}
컨트롤러의 액션은 아래와 같습니다:
[HttpPost]
public ActionResult Text()
{
ViewBag.Notice = Request.Form["Notice"];
return View();
}
이 경우, 공격자가 외부 사이트에서 유사한 폼을 만들어서 사용자의 브라우저가 자동으로 해당 요청을 보낼 수 있습니다. 예를 들어, 공격자는 다음과 같은 HTML 파일을 생성할 수 있습니다:
<html>
<head><title>공격 페이지</title></head>
<body>
<form method="post" action="http://localhost:6060/Home/Text">
<input type="hidden" name="Notice" value="시스템이 해킹되었습니다!" />
<input type="submit" value="공격 실행" />
</form>
</body>
</html>
사용자가 이 페이지를 열고 버튼을 클릭하면, 로컬 사이트의 세션 쿠키를 사용해 공지사항을 무단 변경할 수 있습니다. 이것이 바로 전형적인 CSRF 공격입니다.
방어 방법: AntiForgery 토큰 사용
이 문제를 해결하기 위해, 뷰에 Html.AntiForgeryToken()를 추가하고, 컨트롤러 액션에 [ValidateAntiForgeryToken] 특성을 적용해야 합니다:
@using (Html.BeginForm("Text", "Home", FormMethod.Post))
{
@Html.AntiForgeryToken()
@:공지사항: <input type="text" name="Notice" id="Notice" />
<input type="submit" value="전송" />
}
컨트롤러 코드:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Text()
{
ViewBag.Notice = Request.Form["Notice"];
return View();
}
이제 공격자가 위의 악성 폼을 통해 요청을 보내도, 서버는 토큰 검증을 실패하여 예외를 발생시키며 요청을 거부합니다.
내부 동작 원리
Html.AntiForgeryToken()는 System.Web.WebPages.AntiForgery 클래스의 GetHtml() 메서드를 호출하여, 임의의 값을 생성하고 다음 두 곳에 저장합니다:
- 클라이언트 쿠키: 이름은 기본적으로
__RequestVerificationToken - 폼 내부의 숨김 필드: <input type="hidden" name="__RequestVerificationToken" value="..." />
서버에서는 [ValidateAntiForgeryToken] 특성이 요청의 쿠키 값과 폼 데이터의 토큰 값이 일치하는지 확인합니다. 불일치하거나 토큰이 없으면 InvalidOperationException이 발생합니다.
JavaScript AJAX 요청 처리
AJAX 요청에서도 CSRF 보호를 적용하려면, jQuery 플러그인을 사용해야 합니다. 예를 들어, jqueryToken-1.4.2.js를 포함하고, 다음과 같이 사용합니다:
$.ajaxAntiForgery({
type: "post",
url: "/Event/Mass/AddGroup",
data: {
GroupName: $("#GroupName").val(),
GroupPhones: $("#GroupPhones").val()
},
dataType: "json",
success: function (data) {
if (data) {
alert("그룹 추가 성공");
$.unblockUI();
} else {
alert("추가 실패");
}
}
});
모든 데이터 수정 작업(삽입, 삭제, 업데이트)에는 반드시 CSRF 방어 기법을 적용해야 합니다.
요약
CSRF 공격은 사용자의 인증 상태를 악용하여 의도하지 않은 행동을 수행하게 만듭니다. ASP.NET MVC의 Html.AntiForgeryToken()와 [ValidateAntiForgeryToken] 조합은 이러한 공격을 효과적으로 차단합니다. 이를 통해 신뢰할 수 있는 웹 애플리케이션의 보안을 강화할 수 있습니다.