[엉박사] 1.9 Issues

impala·2023년 1월 12일
0
post-thumbnail

1.9 .Issues

프로젝트를 진행하면서 여러 종류의 에러를 볼 수 있었는데, 그 중 가장 대표적인 두가지 보안 이슈와 해결법을 소개하겠다.

1.9.1 CSRF

CSRF란 Cross Site Request Forgery의 약자로 웹 어플리케이션 취약점의 한 종류이다.

CSRF공격은 공격자가 웹어플리케이션 사용자의 권한을 도용하여 주요 기능을 실행하는 것으로 사용자가 웹사이트에 로그인한 상태에서 피싱이나 XSS등을 통해 CSRF공격코드가 삽입된 페이지를 열면 공격자는 사용자의 권한을 도용하여 사용자가 로그인된 웹사이트에 사용자인척 요청을 보내 비밀번호를 변경하는 등 정보를 탈취하는 방식으로 이루어진다.

장고에서는 CSRF공격을 방지하기 위해 두 가지 작업을 권장한다

  • 'safe'한 HTTP메소드(GET, HEAD, OPTION)가 서버의 상태를 변경할 수 없도록 구현할 것
  • 'unsafe'한 HTTP메소드(POST, PUT, PATCH, DELETE)를 사용할 때에는 항상 유효한 CSRF토큰을 요구하도록 구현할 것

여기서 CSRF 토큰이란 서버가 클라이언트의 세션에게 발급해주는 무작위 난수값으로 클라이언트가 서버로 보내는 요청의 헤더에 이 값을 넣어 보내면 서버는 서버에 저장된 토큰값과 요청헤더에 담겨진 토큰값을 비교하여 신뢰할 수 있는 사용자인지 확인한 뒤 작업을 수행한다.

공식 문서에 따르면 CSRF토큰을 사용하면서 에러를 발생하지 않도록 하기 위해서는 settings.py에 CSRF_TRUSTED_ORIGINS 라는 allowlist를 추가하여 정상 접근 도메인값을 명시해주면 된다.

CSRF_TRUSTED_ORIGINS = ["www.dreung.duckdns.org", "127.0.0.1"]

1.9.2 CORS

CORS란 Cross Origin Resource Sharing의 약자로 다른 도메인의 서버에서 요청을 보냈을 때 리소스를 공유할 수 있도록 하는 메커니즘이다.

CORS에러는 웹 브라우저에서 발생하는 에러로, 웹 브라우저는 기본적으로 SOP(Same-Origin Policy : 동일출처 정책)을 통해 Origin(출처, 도메인)이 다른 곳에서 오는 요청을 신뢰하지 않아 리소스를 공유할 수 없도록 하는데, 프론트엔드 서버에서 백엔드 서버로 HTTP요청을 보내는 경우 두 서버의 Origin이 다르기 때문에 백엔드에서 요청에 따라 데이터를 보내도 브라우저가 이를 막는 경우 발생하는 에러이다.

예를 들어 우리 프로젝트에서 로컬에서 리액트로 프론트엔드 서버를 돌리고, 장고로 백엔드서버를 돌리면 프론트엔드 서버의 Origin은 "localhost:3000", 백엔드 서버의 Origin은 "localhost:8000"으로 두 Origin이 다르기 때문에 브라우저에서 백엔드 서버로 HTTP요청을 보내도 데이터를 받아오지 못하게 된다.

CORS의 동작과정은 다음과 같다

  1. 브라우저가 Origin이 다른 API서버로 요청을 보낼 때, 헤더에 Origin 정보(Scheme, Domain, Port)를 추가하여 전송한다.
  2. 1번의 요청을 받은 API서버는 응답헤더에 Access-Control-Allow-Origin 정보를 추가하여 보낸다.
  3. 응답을 받은 브라우저는 요청헤더로 보낸 Origin값이 응답헤더에 담긴 Access-Control-Allow-Origin에 포함되면 이 요청을 신뢰하고 데이터를 받는다.

위의 방법은 Simple request방식으로 GET, POST등의 메소드에 사용되는 방법이고, PUT, DELETE등 서버의 데이터를 변경하는 요청에 대해서는 같은 방식으로 Preflight요청을 먼저 보내 사이트를 인증한 뒤 본 요청을 보낸다.

즉, API서버에서 CORS설정을 위해서 해야 할 일은

  • CORS를 허용할 도메인들(Access-Control-Allow-Origin)을 설정해두고,
  • 헤더에 Origin을 포함한 요청이 들어오면 Access-Control-Allow-Origin를 응답헤더에 추가하여 보내주는 것이다.

장고에서는 django-cors-header middleware를 통해 이를 수행한다. 프로젝트에 django-cors-header를 적용하는 방법은 아래와 같다.

  1. django-cors-header설치

    $ pip install django-cors-header
  2. INSTALLED_APPS에 'corsheader'추가

    # settings.py
    INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
    ]
  3. MIDDLEWARE에 CorsMiddleware추가

    # settings.py
    MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', 
    ...
    ]
  4. CORS설정 추가

    # settings.py
    # Access-Control-Allow-Origin
    CORS_ALLOW_WHITELIST = [
        "www.dreung.duckdns.org",
        # CORS요청을 허용할 도메인
    ]
    
    # CORS_ORIGIN_ALLOW_ALL : 모든 도메인에 대해 CORS요청 허용
    # CORS_ALLOW_CREDENTIALS : cross-site HTTP요청에 쿠키포함
    # CORS_ALLOW_METHODS : CORS요청헤 허용되는 HTTP METHOD 리스트
    # CORS_ALLOW_HEADERS : CORS요청에 허용되는 non-standard HTTP헤더 목록

0개의 댓글