
다른
출처의 리소스를 사용하는 것을 제한하는 보안 방식
리소스에 접근하기 위해서 인증 토큰이 필요한 서버,
target.com이 있다고 가정하자.해커는 사용자에게 서버의 리소스를 변조하는 스크립트가 담긴 링크,
hack.com
사용자에게 이메일 등으로 보내 피싱한다.사용자는 인증 토큰을 쿠키에 가지고 있는 상태에서
hack.com링크를 클릭하게 된다면
target.com의 리소스를 성공적으로 변조할 수 있을 것이다.
위 상황은 리소스를 가지고 있는 출처와 다른 출처에서 접근하는 상황이다.
SOP는 이와 같은 상황을 방지하기 위해 나온 보안 방식이다.
CSRF
URL 구조에서
Protocol,Host,Port를 합친 것을 말한다.즉, 이 세 요소가 같아야, 같은 출처(Same Origin)라고 볼 수 있는 것이다.

인터넷 상의
리소스 자원 그 자체를 식별하는 문자열 시퀀스
URI 의 하위 개념으로 URL 과 URN 이 있다.
URI=자원의 식별자
네트워크 상에서
리소스의 위치를 나타내기 위한 규약이다.
URL=자원의 위치
리소스에 이름을 부여하는 것을 말한다.
http://www.naver.com/index.html?page=1232950&id=776를 살펴보자
http://www.naver.com/ 서버에 위치한 index.html 페이지는
query string인 page의 값에 따라 여러가지 화면 결과(자원)를 나타나게 된다.따라서
자원의 위치를 나타내는URL은http://www.naver.com/index.html까지가 되고
자원의 식별자를 나타내는URI는http://www.naver.com/index.html?page=1232950&id=776이 된다.
아래의 두 주소는 같은 URL 이면서 다른 URI 가 되는 것이다.
http://www.naver.com/index.html?page=1232950&id=776
http://www.naver.com/index.html?page=9923145&id=122
Q.
http://localhost와 동일 출처인 것은?
1. https://localhost
2. http://locolhost:80
3. http://127.0.0.1
4. http://localhost/api/cors
Answer
2,4
1은 프로토콜이 다른다.
3은 localhost의 ip 주소는 127.0.0.1 이니깐 맞긴하지만
브라우저에서 비교할때 String Value 로 비교를 해서 다른 출처라고 판단한다고 한다."localhost" == "127.0.0.1" ?? ->
False!!!
추가 HTTP 헤더를 사용하여
내 리소스를 다른 출처에서 접근이 가능하도록 권한을 부여하고
이를 브라우저에게 알려주는 체제이다.
OPTIONS메서드를 통해 다른 도메인에 요청이 가능한지 확인하는 작업
요청이 가능하다는 응답을 받으면 그때 부터 실제 요청(ACTUAL REQUEST)을 보낸다.
위 그림은 preflight 요청을 보냈는데 권한이 없다고 응답이 온 경우이다.
Preflight Request
Origin: 요청 출처Access-Control-Request-Method: 실제 요청의 메서드Access-Control-Request-Headers: 실제 요청의 추가헤더
Preflight Response
Access-Control-Allow-Origin: 서버 측에서 허가한 다른 출처Access-Control-Allow-Methods: 서버 측에서 허가한 메서드Access-Control-Headers: 서버 측에서 허가한 헤더Access-Control-Max-Age: Preflight 응답 캐시 시간,초단위
- 매번 Preflight 하는 것은 비효율적이기 때문에 빠른 요청을 위한 캐싱을 위함이다.
CORS 가 나타나기 이전에 만들어진 서버들은
SOP(Same origin policy) request만 가능하다는 전제하에 만들어졌다.CORS 가 나타나면서 보안적인 문제를 발생시킬 수 있게됐는데 이를 위함이다.
CORS 는 클라이언트에서만 나타나는 로그이다.
Preflight 가 없다면 허용하지 않은 다른 출처에서 서버의 리소스를 접근하는 요청을 보냈을 때
요청을 처리하면 안되는데 처리를 하고 CORS 관련 에러 상태 코드를 클라이언트로 보내게 된다.
이러한 이유로 Preflight가 탄생하게 되었다.
Preflight 요청 없이 바로 요청을 보낸다.
Access-Control-Allow-Origin: *은 와일드 카드로 모든 다른 출처를 허용한다는 뜻이다.조건
METHOD:GET,POST,HEAD만 가능Content-Type:
application/x-www-form-urlencoded|multipart/form-data|text/plain만 가능Header:Accept|Accept-Language|Content-Language|Content-Type만 가능
인증 관련 헤더를 포함할때 사용하는 요청이다.
클라이언트 측
credentials: include서버 측
Access-Control-Allow-Credentials : true
->Access-Control-Allow-Origin: *과 같이 쓰면 에러가 발생한다.
프론트 단에서 프록시 서버 설정(개발 환경)
react 라이브러리(0.2.3 이상)를 사용하는 경우,
package.json 에"proxy": "http://localhost:8080"를 추가한다.
직접 헤더 설정
서버에서 CORS 허용
CORS 정책을 설정해줄 Controller에
@CrossOrigin어노테이션을 활용한다.
모든 것을 허용하려면 모든 컨트롤러에 어노테이션을 써야한다.