본문 바로가기
크롬업데이트

2020년 1분기 이슈(서드파티 쿠키, SameSite, Http 차단, UA 중단, ClientHints 제공)

by F.E.D 2020. 3. 29.

다나와 기술블로그 내용을 재구성하였습니다.

서드파티 쿠키 2년내로 사용 불가

서드파티 쿠키는 사용자가 방문한 사이트 내에서 생성되는 쿠키가 아닌 다른 웹사이트에서 들어오는 쿠키를 말합니다.
사용자가 지마켓을 방문한 뒤에 구글 검색을 이용하고 있는데 그 페이지 내에서 지마켓에서 본 상품들이 광고로 뜨는 것을 확인할 수 있습니다. 이런 서드파티 쿠키를 2년 내로 차단하겠다고 구글측에서 발표했습니다.
기존에도 서드파티 쿠키를 차단하는 방법이 있었는데요.

 

출처 : https://ojji.wayful.com/2013/12/Google-Chrome-to-Allow-or-Block-Third-party-Cookie.html

 

광고업계에서는 일대 파란이 예상됩니다. 

본래, 사용자의 기록을 추적하기 위한 행위는 개인정보보호 이슈로 판단되어 사파리, 파이어폭스, 엣지 등은 쿠키를 추적하지 못하게 하거나 서드파티 쿠키 사용을 금지 해 왔습니다.

크롬은 이제 적용하지만 점유율이 높아 매우 타격이 클 것으로 예상됩니다.

 

SameSite 쿠키 이슈

구글은 2월에 크롬 80 버전을 업데이트 하면서 쿠키의 SameSite의 default 값을 "None"에서 "Lax"로 변경했습니다.

SameSite는 크로스 도메인 간의 쿠키 전송에 관한 내용 입니다.

속성으로 다음 3가지가 있습니다. 

None 사용 도메인과 크로스 도메인 모두 허용 모두 허용 높음
Lax 사용 도메인과 크로스 도메인 방식 일부 허용 HTTP GET method, <a>, <link> 방식 허용 낮음
Strict 사용 도메인만 사용 모두 차단 추거의 없음

출처:https://danawalab.github.io/common/2020/04/01/Common-web-issue-1.html

 

기존에는 None이라서 도메인 크로스 도메인과 사용 도메인을 모두 허용해두었기 때문에 CSRF 공격에 취약했습니다.

여기서 CSRF에 대해서 알아봅시다.

CSRF는 Cross Site Request Forgery의 줄임말로

사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 만드는 공격입니다.

 

이해하기 쉽도록 예제 코드를 한번 살펴보겠습니다.

<form method="post" action="http://facebook.com/api/content">
  <input type="hidden" name="register" value="가입하시면 엄청난 혜택을 드립니다." />
  <input type="submit" value="enter or click"/>
</form>

위와 같이 페이스북이나 다른 sns에서 글을 작성할 때 위의 폼이 전송된다고 생각해봅시다.

피싱 사이트에 위의 폼이 자동으로 전송되는 구문이 들어있고 사용자는 페이스북에 글을 작성중입니다.

그렇다면 페이스북의 글을 작성하는 동시에 해당 내용이 submit 되어 사용자의 의도와 상관없이 저 form으로 된 글을 작성하게 되는 것입니다.

 

위와 같은 내용을 방지하기 위한 방법들이 두가지가 있습니다.

 

Referrer 검증
Security Token 사용 (A.K.A CSRF Token)

 

Referrer 검증은 백엔드에서 도메인을 체크하여 막는 방법입니다.

Security Token 사용은 프론트에서 세션에 저장된 토큰 값과 요청 파라미터에 전달되는 토큰 값이 일치하는 지 검증하는 방법입니다.

위 두방법 역시 같은 도메인 내의 XSS 공격에는 취약합니다.

그나마 Security Token 방법 중 괜찮은 방법이 Double Submit Cookie 검증입니다.

 

Double Submit Cookie 검증은 세션을 사용할 수 없는 환경에서 사용할 수 있는 방법입니다.

웹브라우저의 Same Origin으로 자바스크립트를 사용할 시에 타 도메인의 쿠키 값에 접근하지 못하는 것을 이용한 방어 기법입니다.

요청 시 난수 값을 생성하여 쿠키에 저장하고 동일한 난수 값을 요청 파라미터에도 저장하여 서버로 전송합니다.

서버단에서 쿠키의 토큰 값과 파라미터의 토큰 값이 일치하는지 검사합니다.

서버에 따로 토큰 값을 저장할 필요가 없어 편리하고,

피싱 사이트에서는 도메인이 다르기 때문에 사용자가 작성중인 sns 도메인에 쿠키 값을 저장하지 못합니다. 

 

* front

/** 
 * Generate 256-bit BASE64 encoded hashes * 
 *
 * @return {string} 
 */


var generateCsrfToken = function() {
    function generateRandomString(length) {
        var text = '';
        var possible =
            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        for (var i = 0; i < length; i++) {
            text += possible.charAt(
                Math.floor(Math.random() * possible.length),
            );
        }
        return text;
    }
    return btoa(generateRandomString(32));
};

// setting cookie
var setCookie = function(cname, cvalue) {
    document.cookie = cname + '=' + cvalue + ';path=/';
};


// setting header cookie (token)
jQuery.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (
            !(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))
        ) {
            var csrfToken = generateCsrfToken();
            setCookie('CSRF_TOKEN', encodeURIComponent(csrfToken));
            xhr.setRequestHeader('_csrf', csrfToken);
        }
    },
});


 

* back

// check header
String paramToken = request.getHeader("_csrf");

// check cookie csrf token
String cookieToken = null;

for (Cookie cookie : request.getCookies()) {
  if ('CSRF_TOKEN'.equals(cookie.getName())) {
      cookieToken = URLDecoder.decode(cookie.getValue(), 'UTF-8');
      
      // Expiring cookie preventing from reusing
      cookie.setPath('/');
      cookie.setValue('');
      cookie.setMaxAge(0);
      response.addCookie(cookie);
      
      break;
  }
}

// check same token
if (cookieToke.equals(paramToken)) {
    return true;
} else {
    return false;
}

default 속성을 "none"으로  사용하려면 쿠키에 Secure 속성을 부여하여 HTTPS 환경에서만 사용되어야 합니다.

iframe으로 이루어진 서비스 및 인증 대행 서비스, 결제 모듈 등에 다양한 영향을 줄 것입니다.

 

HTTPS 아닌 HTTP로 다운로드는 차단 예정

출처 : https://danawalab.github.io/common/2020/04/01/Common-web-issue-1.html

* 다운로드 차단 일정입니다.

2020.03 Chrome 81 모든 HTTP 다운로드시 콘솔 경고 기록
TLS 1.0, 1.1 지원 중단
2020.04 Chrome 82 실행 파일에 대한 HTTP 다운로드 경고 노출
2020.06 Chrome 83 실행 파일에 대한 HTTP 다운로드 차단
압축 파일 및 디스크 이미지에 대하 HTTP 다운로드 경고 노출
2020.08 Chrome 84 압축 파일 및 디스크 이미지에 대하 HTTP 다운로드 차단
문서 형식 파일에 대한 HTTP 다운로드 경고 노출
2020.09 Chrome 85 문서 형식 파일에 대한 HTTP 다운로드 차단
미디어 형식 파일에 대한 HTTP 다운로드 경고 노출
2020.10 Chrome 86 미디어 형식 파일에 대한 HTTP 다운로드 차단

 

User-Agent 제거 예정 -> Client Hints 사용 장려

 

https://wiki.developer.mozilla.org/ko/docs/Glossary/Client_hints

 

Client hints(클라이언트 힌트)

Client Hints는 클라이언트 장치 및 에이전트별 기본 설정 목록을 확인할 수 있도록 사전 컨텐츠 체크를 위한  HTTP request header 입니다.

developer.mozilla.org

User-Agent 대신에 Client Hints 사용을 장려합니다.

User-Agent는 점차 사라질 것입니다.

크롬 85까지 지원 중단 계획을 세우고 점진적으로 적용 중입니다.

 

날짜크롬 버전처리 내역

2020.03 Chrome 81 User-Agent 문자열을 읽는 웹페이지에 대해 크롬 콘솔에 경고를 표시할 계획이며, 이를 통해 개발자들은 웹사이트 코드를 조정할 수 있도록 유도
2020.06 Chrome 83 User-Agent 문자열에서 Chrome 브라우저 버전을 동결하고 OS 버전을 통합
2020.09 Chrome 85 User-Agent 데스크톱 OS 문자열을 데스크톱 브라우저의 공통 값으로 통합, 모바일 OS/기기 문자열을 비슷한 공통의 값으로 통합한다.

위와 같이 User-Agent 내용을 통합할 것이기 때문에 걱정하지 말고 점진적으로 적용하면 될 것 같습니다.

 

클라이언트를 사용한 이미지의 예시 코드를 다음과 같이 확인할 수 있습니다.

 

<picture>
  <source srcset="company-photo-256w.webp 256w,
                  company-photo-512w.webp 512w,
                  company-photo-768w.webp 768w,
                  company-photo-1024w.webp 1024w,
                  company-photo-1280w.webp 1280w"
          type="image/webp">
  <img srcset="company-photo-256w.jpg 256w,
               company-photo-512w.jpg 512w,
               company-photo-768w.jpg 768w,
               company-photo-1024w.jpg 1024w,
               company-photo-1280w.jpg 1280w"
       src="company-photo-256w.jpg"
       sizes="(min-width: 560px) 251px, 88.43vw"
       alt="The Sconnie Timber Staff!">
</picture>

 

서비스 워커에 명령을 해놓고 사용할 수도 있습니다.

self.addEventListener("fetch", event => {
  let dpr = event.request.headers.get("DPR");
  let viewportWidth = event.request.headers.get("Viewport-Width");
  let width = event.request.headers.get("Width");

  event.respondWith(async function() {
    // Do what you will with these hints!
  }());
});


if ("connection" in navigator) {
  // Work with netinfo API properties in JavaScript!
}

가장 중요한 부분은 역시 클라이언트 힌트를 통해서 우리는 매우 점진적이고 최적화 할 수 있는 이미지를 제공함으로써 조금 더 나은 웹 환경을 만들 수 있다는 것입니다.

 

 

 

 

 

출처: https://itstory.tk/entry/CSRF-공격이란-그리고-CSRF-방어-방법
출처 : https://danawalab.github.io/common/2020/04/01/Common-web-issue-1.html

출처 : https://wiki.developer.mozilla.org/ko/docs/Glossary/Client_hints

 

Client hints(클라이언트 힌트)

Client Hints는 클라이언트 장치 및 에이전트별 기본 설정 목록을 확인할 수 있도록 사전 컨텐츠 체크를 위한  HTTP request header 입니다.

developer.mozilla.org

 

댓글