# 사이트 보안점검을 해봅시다

- Author: @baealex
- Published: 2021-09-28
- Updated: 2023-03-27
- Source: http://blex.me/@baealex/%EB%B3%B4%EC%95%88
- Tags: 엔진엑스, 보안

---

https://observatory.mozilla.org/ 모질라에서 제공하는 사이트 보안 점검을 받아보았다. 무심코 그냥저냥 보통 점수가 나오리라 생각했지만 충격적이게도 15점, F 등급을 받았다. 두둥 🥳

![](https://static.blex.me/images/content/2021/9/28/21_6h6ESoS5MvlnNRhfYPRU.jpg)

사실 보통 점수가 나왔으면 안하고 넘어가려 그랬는데 F는 또 못참지. 어떠한 보안상의 문제가 있는지 각 항목이 의미하는 것은 무엇이며 어떻게 적용하는지 알아보도록 하자. 여기서는 `NginX`를 활용한다.

<br>

#### X-Frame-Options 

다른 사이트 내의 `iframe`에 내 사이트를 노출할 수 있도록 할 것인지 차단할 것인지 설정하는 헤더이다. 다른 사이트에서 노출돼면 안되는 이유를 대부분의 경우 클릭재킹을 예로드는데, 실제로 해보니 파폭, 크롬, IE 모두 타 도메인의 DOM에 접근이 안되던데(?) 클릭재킹을 어떻게 한 건지 연구해 봐야겠다.

###### 적용방법

```nginx
add_header X-Frame-Options "DENY";
```

옵션은 다음과 같다.

- `DENY` : 거부
- `SAMEORIGIN` : 동일 도메인에서는 가능
- `ALLOW_FROM <ORIGIN> <ORIGIN> ...` : \<ORIGIN\>은 허용
	
<br>

#### Content-Security-Policy

콘텐츠 보안 정책, 어떤 도메인에서 오는 컨텐츠만 허용할 것인지 설정하는 헤더이다. 예를들어 공격자는 우리 사이트에 방문하여 인라인 스크립트를 삽입하거나 악의적인 도메인에 비치된 스크립트를 삽입하여 공격(XSS)하고자 할 것이다. 이 헤더를 설정하면 이러한 공격을 방지할 수 있다.

###### 적용방법

```nginx
add_header Content-Security-Policy "script-src 'self'; style-src 'self'; child-src *.youtube.com;";
```

모양은 대략 위와 같으며 제어할 수 있는 속성은 다음과 같다.

- `base-src` : base 태그의 링크
- `child-src`: 프레임 콘텐츠 링크(iframe 등)
-  `connect-src` : XHR, WebScoket, EventSource 주소
- `form-action`: form 태그의 end point
- `script-src` : 스크립트 파일
- `style-src` : 스타일시트 파일
- `font-src`: 폰트 파일
- `img-src` : 이미지 파일
- `media-src` : 동영상 및 오디오 파일
- `object-src` : 플래시 등 기타 플러그인

속성의 매핑은 다음과 같다.

- `none` : 아무것도 허용하지 않음
- `self` : 현재 도메인과 동일, 하위 도메인 포함하지 않음
- `unsafe-inline` : 인라인 자바스크립트 및 CSS를 허용
- `unsafe-eval` : eval 메커니즘 허용

<br>

#### Strict-Transport-Security

일반적으로 HTTPS를 강제하는 방식은 HTTP로 요청을 보냈을때 HTTPS로 302 Redirect 시키는 방법을 사용하다. 그런데 이 과정속에 보안 결함이 있으므로 적용이 필요한 헤더다. 이 헤더를 적용하면 클라이언트가 다음에 다시 HTTP로 사이트를 방문할때 서버에 도달하지 않고 HTTPS로 강제로 전환한다.

###### 적용방법

```nginx
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
```

옵션은 다음과 같다.

- `max-age` : 해당 시간만큼 설정이 유지된다. 따라서 사이트는 이 기간동안 HTTPS 통신을 지원해야 한다. 위 예시는 2년으로 적용된 상태. 가장 권장하는 값이며 1년으로 설정하려면 31536000로 기입하면 된다.
- `includeSubdomains` : 이 사이트의 하위 도메인도 같은 규칙을 따른다. (not require)
- `preload` : 클라이언트 측에서 더 이상 사이트의 HTTP와 연결되지 않도록 설정한다. (not require)

<br>

#### X-Content-Type-Options

HTTP에서 응답된 Content-Type과 다른 용도로 사용되는 것을 막는다. 예를들어 확장자는 `img` 파일이지만 이것이 실제로 스크립트 파일이라면? 이 위장된 스크립트 파일을 스크립트 태그에서 호출하면 어떻게 될까? 정상적으로 스크립트로 읽어들인다. 이러한 경우를 방지하기 위해서 적용하는 헤더이다.

###### 적용방법

```nginx
add_header X-Content-Type-Options "nosniff";
```

다른 옵션은 존재하지 않는다.

<br>

#### X-XSS-Protection

IE, Chrome, Safari에서 지원되는 헤더로 XSS 공격이 감지되면 페이지 로드를 중지시킨다. 아까 위에서 CSP(Client-Security-Police)를 적용하면 인라인 스크립트를 사용할 수 없다고 말했었는데 CSP 헤더가 지원되지 않는 구형 브라우저를 위한 헤더로 적용하는 것을 권장한다.

###### 적용방법

```nginx
add_header X-XSS-Protection "1;mode=block";
```

옵션은 다음과 같다. 
- `0` : XSS 필터링 비활성화
- `1` : XSS 필터링 활성화 (XSS 공격이 감지되면 안전하지 않는 부분만 제거한 뒤 랜더링) (기본값)
- `1; mode=block` : XSS 필터링 활성화 (XSS 공격이 감지되면 랜더링 중단)

<br>

#### 적용후

![](https://static.blex.me/images/content/2021/9/28/22_9txAKwiEhP07UW8ajLws.jpg)

위 항목을 전부 적용하여 많이 오르긴 했지만, 설정키가 필요한 구글 광고랑 마소 Clarity를 인라인 스크립트로 사용하고 있어서 CSP 스크립트에  'unsafe-inlie' 옵션을 줬더니 이것도 감점 요소였다.

@gif[https://static.blex.me/images/content/2021/6/2/13_J4GZA6PSvnqo0B3RWP2p.mp4]

난감한걸
