[번역] Working with AJAX, CSRF & CORS

hyuckhoon.ko·2020년 7월 5일
1

What I learned in wecode

목록 보기
78/109

출처 : https://www.django-rest-framework.org/topics/ajax-csrf-cors/




cors 및 CSRF 관련하여 구글링을 하던 도중 좋은 영문자료가 있어서
번역(의역)을 해봤다. 프로젝트를 하며 알아야 하는 사항이며,
웹 개발자라면 반드시 알아야 하는 정보이기에 공유하려고 한다.
영문 자료 출처는 맨 위에 명시했다.
단순히, 해석만 하기보다 의역을 통해 내 생각도 첨가하였다.




Working with AJAX, CSRF & CORS

"Take a close look at possible CSRF / XSRF vulnerabilities on your own websites. They're the worst kind of vulnerability — very easy to exploit by attackers, yet not so intuitively easy to understand for software developers, at least until you've been bitten by one."
— Jeff Atwood

(번역)우리의 웹사이트가 맞딱뜨리는 가장 최악의 취약점은 CSRF / XSRF 입니다.
해커들이 쉽게 악용할 수 있고, 개발자가 직접 호되게 당하지 않는 이상 제대로 알기 어려운 부분이기도 합니다. - Jeff Atwood

(내 생각) 나 역시 프로젝트를 진행하며 모델링 및 API 개발에만 급급했지
장고 웹 프레임워크의 settings.py에 추가적으로 작성해야 했던 cors 등의 코드의 배경은 알지 못했었다. 이번 번역을 계기로 내가 쓰는 코드가 어떤 의미를 갖는지 알아보려고 한다.




1. Javascript clients

"If you’re building a JavaScript client to interface with your Web API, you'll need to consider if the client can use the same authentication policy that is used by the rest of the website, and also determine if you need to use CSRF tokens or CORS headers."

(번역)"우리의 웹 API들이 자바스크립트 클라이언트들과 정보를 주고받기 위해 고려해야할 사항이 몇가지 있다.
1) 클라이언트에게 적용한 유저 인증 방식을 다른 페이지의 기능 아니면 다른 웹들의 요청에도 동일하게 적용할지,
2) 아니면 CSRF 토큰이나 CORS 헤더를 통한 인증방식을 적용할지
말이다.




"AJAX requests that are made within the same context as the API they are interacting with will typically use SessionAuthentication. This ensures that once a user has logged in, any AJAX requests made can be authenticated using the same session-based authentication that is used for the rest of the website."

(번역) AJAX request의 경우를 한 번 보자.
어떤 홈페이지가 있고, 특정 페이지가 있다고 하자. 그 페이지에 사용되는 API의 AJAX 요청의 경우는 대개 세션인증방식을 사용한다.
즉, 유저가 일단 로그인했다면 다른 페이지에서도 유저 인증이 필요할때,
맨 처음 발급받았던 세션인증을 활용한다는 것이다.




"AJAX requests that are made on a different site from the API they are communicating with will typically need to use a non-session-based authentication scheme, such as TokenAuthentication."

(번역)항상 그렇게 할 수는 없는 노릇이다. 각기 다른 웹들의 API들이 있을텐데, 다양한 웹들로부터 오는 AJAX 요청의 경우 대개 비세션 인증을 사용한다. 즉, 토큰 인증을 사용해야 한다.

(내 생각) 예를 들어, 지난주에 샤넬 홈페이지 클론 프로젝트를 진행했었다.
회원가입을 하고 위시리스트에 제품을 넣을때, 세션인증 방식을 택할 수 있고 토큰 인증방식을 채택할 수도 있다.
하지만, 만약 다른 웹에서 API 요청들에 대해선 세션인증 방식을 고수할 수 있을까? stateless한 HTTP의 특성상, 다른 웹에서 오는 여러 요청들이 유저의 요청인지, 아닌지 알 수가 없는 노릇이다. 이땐 토큰 인증을 진행한다.






2. CSRF protection

"Cross Site Request Forgery protection is a mechanism of guarding against a particular type of attack, which can occur when a user has not logged out of a web site, and continues to have a valid session. In this circumstance a malicious site may be able to perform actions against the target site, within the context of the logged-in session."

우리말로 CSRF란 사이트 간 요청 위조라고 번역된다.
그리고 CSRF Protection은 사이트 간 요청 위조 방지대책이라고 번역될 수 있겠다.
어떤 경우에 발생되는 것일까?

현재, 유저가 샤넬 홈페이지에서 로그아웃하지 않은 상태라고 해보자.
즉, 그말은 샤넬 홈페이지에서 그 유저가 유효한 세션인증 정보를 갖고 있는 상태란 말이다.

이때 악의적인 웹들에서 해당 유저가 머물고 있는 페이지에서 마치 해당 유저인 것 마냥 작업을 수행할 수가 있다. 샤넬 게시판에 악성 URL을 게시하여 진짜 유저가 클릭을 유도하게 하는 등 말이다. 위조 코드가 삽입된 해당 게시글 혹은 url을 클릭하면 공격에 노출된 상태다.

(위키백과 내용 추가) 일단 사용자가 웹사이트에 로그인한 상태에서 사이트간 요청 위조 공격 코드가 삽입된 페이지를 열면, 공격 대상이 되는 웹사이트(여기서는 샤넬 홈페이지)는 해당 명령이 유저로부터 발송된 것으로 판단한다. 즉, 해커가 유저의 정보를 조작하거나 빼내올 수 있다.




"To guard against these type of attacks, you need to do two things:

Ensure that the 'safe' HTTP operations, such as GET, HEAD and OPTIONS cannot be used to alter any server-side state.
Ensure that any 'unsafe' HTTP operations, such as POST, PUT, PATCH and DELETE, always require a valid CSRF token.
If you're using SessionAuthentication you'll need to include valid CSRF tokens for any POST, PUT, PATCH or DELETE operations.

In order to make AJAX requests, you need to include CSRF token in the HTTP header, as described in the Django documentation.

(번역) 이러한 공격들에 대비하기 위해 우리가 할 수 있는 것은 다음과 같다.

1) GET, HEAD 그리고 OPTIONS와 같은 안전한 HTTP 요청을 사용하여 서버의 데이타들이 변경되고 조작되지 않게 한다.

2) POST, PUT, PATCH, DELETE는 모두 서버의 (데이타베이스)데이타를 조작하는 HTTP 요청들이다. 이러한 요청에는 반드시 CSRF 토큰을 유저에게 요청해야 한다.(stateless)

3) 만약 세션인증 방식을 사용하고 있다면, CSRF 토큰 인증 방식을 채택해야 만 할 것이다.

--> 장고 문서에서 기술하고 있듯이, AJAX 요청을 할때
HTTP헤더에 CSRF 토큰을 넣어야 한다.




3. CORS

"Cross-Origin Resource Sharing is a mechanism for allowing clients to interact with APIs that are hosted on a different domain. CORS works by requiring the server to include a specific set of headers that allow a browser to determine if and when cross-domain requests should be allowed."
(번역)
CORS는 우리말로 교차 출처 리소스 공유다.
다른 웹의 API들과 상호작용할 수 있게 하는 것이다.

하지만 보안을 위해 동일 출처 정책(same-origin policy)이 존재한다.
외부서버의 포트번호나 도메인이 웹의 그것들과 다를 경우, 웹은 요청한 데이터를 block해 버린다. 즉, 통신을 할 수가 없게 된다.

CORS는 서버가 도메인 간 요청이 허용되는지 여부와 시기를 브라우저가 결정할 수 있도록 특정 헤더 세트를 포함하게 한다.

(위키백과 참조 내용) CORS는 교차 출처 요청을 허용하는 것이 안전한지 아닌지를 판별하기 위해 브라우저와 서버가 상호 통신하는 하나의 방법을 정의한다.




"The best way to deal with CORS in REST framework is to add the required response headers in middleware. This ensures that CORS is supported transparently, without having to change any behavior in your views."

(번역)
가장 좋은 방법은 미들웨어(middelware)에 필수 응답 헤더를 추가하는 것이다. 미들웨어에만 필수 응답 헤더를 추가함으로써 뷰의 동작을 변경하지 않고도 CORS를 투명하게 지원할 수 있다.

0개의 댓글