[error] Refused to load the script 'https://www.google-analytics.com/analytics.js

James An·2022년 10월 26일
0

42cabi

목록 보기
8/8
post-custom-banner

문제 상황

  • 9월까지만해도 dev로 배포된 서비스에서 gaTracker를 수행하여 페이지뷰를 정상적으로 측정하고 있었던 상황에서 특정 시점부터 log에 아래와 같은 error와 함께 정상적으로 ga가 적용되지 않고 있었다...

  • 음.. CSP가 무엇인지는 모르겠지만 이 문제로 인해 튕겨내고 있는 듯하다.

    CSP(Content-Security-Policy)는 웹사이트에서 XSS(Cross Site Scripting)공격을 막기 위해 만들어진 정책으로써 인라인 자바스크립트 및 css를 넣지 못하도록 하는 것이 목적이다.

해결 과정

원인 파악

  • https://developers.google.com/tag-platform/tag-manager/web/csp?hl=ko

  • CSP와 google analytic가 연관된 부분에 대한 해당 링크를 참고해보면 구글에서는 유니버설 애널리틱스(Google 애널리틱스) 태그를 사용하려면 CSP에 다음 지시어가 포함되어야한다고 알려주고 있다.

    script-src: https://www.google-analytics.com https://ssl.google-analytics.com
    img-src: https://www.google-analytics.com
    connect-src: https://www.google-analytics.com
  • csp-evaluator를 사용해서 현재 dev로 배포된 사이트인 https://cabidev.42seoul.io/ 의 CSP를 진단해보면 아래와 같다.

  • CSP에서 지시어(directive)는 여러 종류가 있지만 script-src, img-src, connect-src 세 종류에 대해 적용이 필요했으므로 각각에 대해 간단히 알아보면
    script-src: JavaScript 및 WebAssembly 리소스에 대한 유효한 소스를 지정
    img-src: image 및 favicon의 유효한 소스를 지정
    connect-src: script interface를 사용하여 로드할 수 있는 URL을 제한

  • 또한 지시어에 적용할 수 있는 여러 키워드도 존재한다.
    none : 리소스 로드를 허용
    self : 현재 출처의 리소스만 허용

  • script-src가 self로 지정되어있고, connect-src가 존재하지 않아(존재하지 않으면 무슨 키워드...?) google analytics에 대해 허용하지 않는건가라는 생각이 들었다.

CSP 적용

// example
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

// google analytics
<meta http-equiv="Content-Security-Policy" content="script-src https://www.google-analytics.com https://ssl.google-analytics.com,
                                                    img-src https://www.google-analytics.com, 
                                                    connect-src https://www.google-analytics.com">
  • front-end에서 index.html의 <head> 태그에 작성해도 CSP 지시어들이 올바르게 적용이 되지 않았고, 문제는 여전히 존재했다.
  • 혹시 CSP 설정을 back-end에서도 해주고 있나라는 생각이 들었고, back-end의 CSP 관련 설정을 찾아봤더니
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ConfigService } from '@nestjs/config';
import helmet from 'helmet';
import { initializeTransactionalContext } from 'typeorm-transactional';
import { LogLevel } from '@nestjs/common';


async function bootstrap() {
  [...]
  app.use(helmet());
  await app.listen(port);
  [...]
}
bootstrap();
  • helmet 라이브러리를 사용할 때 app.use(helmet()); 에서 기본적으로 CSP 설정이 된다는 사실을 알 수 있었다.
  • 생각해보면 front에서 설정을 따로 해주지 않았는데 csp-evaluator에서 많은 양의 지시어가 설정되어 있던 부분에서 이상함을 느꼈어야했다.
app.use(helmet({ contentSecurityPolicy: false }));
  • 해당 코드에 CSP 옵션을 false로 설정하게 되면 아래와 같이 CSP 설정이 해제된 걸 확인할 수 있다.
  • 문제 해결 후 ga도 정상적으로 추적되는 걸 확인했다.

참고

profile
born 2 code :)
post-custom-banner

0개의 댓글