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에 대해 허용하지 않는건가라는 생각이 들었다.
// 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">
<head>
태그에 작성해도 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 설정이 된다는 사실을 알 수 있었다.app.use(helmet({ contentSecurityPolicy: false }));