Express 웹사이트 보안 강화하기_CSP

이애옹·2023년 3월 8일
0

Node.js

목록 보기
30/32

📝 CSP란?

Helmet을 구성하는 미들웨어 중 하나인 CSP에 대해 알아보려 한다.

Helmet 모듈을 사용하여 Express 웹 사이트를 개발 하는 경우, 다음과 같은 오류가 발생할 수 있다.

Refused to load the script 'https://cdn.amcharts.com/lib/4/themes/dataviz.js' because it violates the following Content Security Policy directive: "script-src 'self' *.googleapis.com 'unsafe-inline' 'unsafe-eval' . Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

위 오류는 https://cdn.amcharts.com/lib/4/themes/dataviz.js 스크립트가 Content Security Policy(CSP) 정책을 위반하고 있다는 것을 나타낸다.

CSP는 웹 애플리케이션에서 안전하지 않은 리소스(예: 스크립트, 스타일, 이미지 등)로부터 공격을 방지하는 데 사용되는 웹 보안 정책인데, CSP를 구성 할 때에는 사용하려는 자원이 허용되는 출처를 명시해야 한다.

즉, 위 오류는 명시되지 않은 자원을 가져오려고 할때, Helmet에서 해당 자원을 위험한 파일이라고 인식하여 막고 있기 때문에 발생하는 에러인것이다 !!!

📝 CSP 사용 방법

그렇다면, 내가 일부 자원을 외부에서 가져오고 싶을 때는 어떻게 해야할까??

app.js에 다음과 같은 소스 코드를 추가하면 된다.

const cspOptions = {
  directives: {
    ...helmet.contentSecurityPolicy.getDefaultDirectives(),
    "script-src": [
      "https://cdn.amcharts.com"
    ]
  }
};


app.use(helmet({
  contentSecurityPolicy: cspOptions,
}));

이렇게 작성하면, https://cdn.amcharts.com 해당 페이지에서 원하는 자원을 가져올 수 있다..

참고로, cspOptions로 따로 안빼고 안에 작성해도 되지만, option으로 따로 빼고 싶은 경우

cspOptionsapp.use(helmet({ ... }))의 인자로 사용하기 전에 선언하고 초기화해야 한다!!

📝 CSP 정책과 속성

위 예제에서는 script-src 로 작성하여 자원을 가져왔는데, 해당 속성은 Javascript 등 웹에서 실행 가능한 스크립트에 대한 정책이다.

그 외 정책은 다음과 같다.

  • default-src : 모든 리소스에 대한 정책
  • script-src : Javascript 등 웹에서 실행 가능한 스크립트에 대한 정책
  • object-src : 플러그인, 오브젝트에 대한 정책
  • style-src : style, 즉 css에 대한 정책
  • img-src : 이미지에 대한 정책
  • media-src : video, audio에 대한 정책
  • font-src : font에 대한 정책
  • connect-src : script src로 불러올 수 있는 url에 대한 정책
  • form-action : form 태그 내 action 부분에 대한 정책

그 외에도 다양하게 있다~~ 일단 사용하는건 저정도 인 것 같다.

따라서, script-src 속성 외에도 좀 더 다양한 속성을 추가하고 싶다면

app.use(helmet())
app.use(csp({
  directives: {
    defaultSrc: [서버 주소],
    scriptSrc: [서버 주소],
    imgSrc: [서버 주소, '사용하는 이미지 CDN경로', 'img.icons8.com'],
    styleSrc: [서버 주소,
      '*.fontawesome.com',
      '*.jsdelivr.net',
      '*.fonts.googleapis.com'],
    fontSrc: [
      '*.googleapis.com',
      '*.jsdelivr.net'
      '*.fontawesome.com'
    ]
  }
}))

이런식으로 작성 해 주면 된다.

속성안에 있는 값의 종류는 다음과 같다.

  • * : 모든 값을 허용한다.
  • none : 아무값과도 일치하지 않는다.
  • self : 현재 웹서버에서 가지고 있는 동일한 url값을 허용한다. *"' '" 형식으로 작성한다.
  • unsafe-inline : 인라인 자바스크립트 및 CSS를 허용한다. self와 같은 형식으로 작성한다.
  • unsafe-eval : eval같은 텍스트-자바스크립트 매커니즘을 허용한다.
  • default-src * : 모든 컨텐츠의 소스는 모든 사이트 허용
  • 특정 호스트명 : 특정 주소값이 있을 경우 ' ' 형식으로 작성한다.

👀 참고자료

profile
안녕하세요

0개의 댓글