본문 바로가기
HTML CSS

XSS CSRF CORS

by 짱닭 2020. 11. 14.
반응형

XSS (Cross-Site Scripting)

웹사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점
서버에 문자열이 아니라 script 태그와 함수를 보내서 비정상적인 데이터를 서버에 전달하여,
권한이 없더라도 script를 통해 공격하는 방법.

예방
웹 애플리케이션에서 사용자로부터 입력받은 입력값을 제대로 검사하거나,
서버에서 입력 값 필터링을 통해 공격을 예방할 수 있다.

주로 다른 웹사이트와 정보를 교환하는 식으로 작동하므로 Cross-Site Scripting이라 한다.

CSRF (XSRF)

인증정보 탈취
사용자는 인증정보를 가진 채(로그인한 상태)로 해커의 링크를 누르면
해커는 인증(로그인) 정보를 가로채서 이를 이용해 사용자가 요청한 것 처럼 위조된(공격) 요청을 보낸다.

예방
백엔드단에서 request 의 referrer를 확인해서 domain이 일치하는지 검사한다.
일반적으로 referrer 검증만으로 대부분의 CSRF 공격을 방어할 수 있다.

referrer 검증이 불가능하다면, Security Token을 활용한다.
사용자의 세션에 임의의 난수값을 저장하고 사용자의 요청마다 해당 난수 값을 포함시켜 전송한다.
이후 백엔드단에서 요청을 받을 때마다 세션에 저장된 토큰 값과 요청 파라미터에 전달되는 토큰 값이 일치하는지 검사한다.

참고 : itstory.tk/entry/CSRF-%EA%B3%B5%EA%B2%A9%EC%9D%B4%EB%9E%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-CSRF-%EB%B0%A9%EC%96%B4-%EB%B0%A9%EB%B2%95

CORS (Cross-Origin Resource Sharing)

현재 내가 있는 도메인에서 다른 도메인 서버의 API를 사용해야 할 때 현재 도메인에서 다른 도메인 API 서버에 요청을 하는 것을
cross-origin 이라 하는데, 기존엔 이 방법이 보안을 이유로 막혀있었다.(SOP Same-Origin Policy)
하지만 개발자들의 필요에 의해 공식적으로 크로스 도메인 요청을 허용해야 했다.
그래서 등장한 것이 CORS.

웹 앱을 사용하는 사용자를 보호하기 위한 목적이 있다.

CORS가 작동하기 위해서
프론트엔드에서 헤더에 CORS관련 옵션을 넣어주어야 하고,
서버에선 response header에 해당 프론트엔드 옵션을 허용한다는 설정이 필요하다.

작동순서
1.클라이언트에서 HTTP의 OPTIONS 메서드를 사용해서 preflight(사전요청)를 보내서 서버가 해당 요청을 응답해줄 수 있는지
먼저 확인한다. request
2.서버에서 허용한다는 응답을 한다. response
3.클라이언트에서 원래 요청하려던 request를 다시 보낸다.(필요한 HTTP 메서드(GET or POST)를 사용해서) request
4.서버에서 응답한다. response

preflight
클라이언트의 요청이 서버에서 허용되는 요청인지 확인하기 위해서 원래 요청 전에 보내는 사전 요청.
서버에서 preflight를 받고 허용하지 않는다면 클라이언트가 원래 보내려던 요청은 보낼 수 없고,
허용한다면 클라이언트는 원래 보내려던 요청을 마침내 보낸다.

같은 출처를 구분하는 방법
두 URL의 구성 요소 중 Scheme, Host, Port, 이 3가지만 동일하면 된다.

https://jjanddak.github.io:80 라는 출처를 예로 들면
스킴 : https://
호스트 : jjanddak.github.io
포트 : 80

같은 출처 취급
https://jjanddak.github.io/about
https://jjanddak.github.io/about?q=짱닭
https://user:password@jjanddak.github.io

~다른 출처 취급
~

http://jjanddak.github.io 스킴이 다름
https://api.github.io 호스트가 다름
https://jjanddak.naver.com 호스트가 다름
https://jjanddak.github.com 호스트가 다름
https://jjanddak.github.io:8000 브라우저의 구현에 따라 다름

참고 : https://evan-moon.github.io/2020/05/21/about-cors/

simple requests
CORS preflight를 보내지 않는 경우.

1.셋중의 하나의 리퀘스트여야 한다.

  • GET
  • POST
  • HEAD

2.자동으로 붙는 헤더가 아니면 안된다. (다음중 하나)

3.헤더에 content-type이 다음 세 가지중 하나여야 한다.

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

additional

클라이언트를 다음과 같이 serve 유틸리티를 이용해 실행하고, 서버의 Access-Control-Allow-Origin을 클라이언트의 origin으로 특정해보세요. 지정한 origin외에 다른 곳에서는 접근이 안되나요?

index.html:1 Access to fetch at 'http://localhost:5000/upper' from origin 'http://localhost:52330' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains the invalid value 'origin'. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
=위와같은 오류가 콘솔창에 발생하고, origin이 아닌 도메인에서 CORS 위반으로 인해 접근이 안된다.

클라이언트 코드(App.js)의 요청 헤더를 수정해봅시다. Content-Type을 text/plain으로 바꿔보세요. preflight request가 발생하나요? 발생하지 않는다면 그 이유는 무엇일까요?
=OPTIONS 메서드로 preflight 요청이 가지 않는다.
이는 preflight 요청을 보내지 않는 simple request에 속하기 때문.

반응형

댓글