보안 강화 HTTP Header 사용
HTTP 헤더에는 보안을 강화하기 위한 여러 헤더가 있습니다.
HttpOnly 설정
서버에서 쿠키 설정시 HTTP 헤더에 HttpOnly 속성을 설정한다면 브라우저는 자바스크립트등 사용자 단의 스크립트에서 브라우저내의 쿠키 접근을 차단합니다.
이러면 실수로 인해 웹 애플리케이션에 XSS 취약점이 있어도 공격자는 쿠키를 가져갈 수 없게 되므로 설정해 두는게 좋습니다.
보통 이 값은 웹 애플리케이션 개발자가 WAS 설정을 통해 모든 Set cookie 헤더에 출력해야 하지만 만약 아파치 웹 서버를 사용할 경우 Header 지시자를 통해 강제로 설정하도록 할 수 있습니다.
또 쿠키 설정시 Secure 속성을 설정할 수 있는데 서버에서 이 값을 설정할 경우 브라우저는 https 로 세션이 보호되지 않는다면 서버로 쿠키를 전송하지 않으므로 습관적으로 두 개의 보안 속성을 설정하는 것이 좋습니다.
<?php setcookie("TestCookie", "Value", time()+3600, "/", "secure.com"); /* expire in 1 hour */
PHP 의 경우 setcookie 에 HttpOnly와 Secure 옵션을 추가할 수 있는 파라미터가 있습니다.
<VirtualHost *:80> ServerName www.secure.com ## 모든 Set-Cookie 헤더 뒤에 HttpOnly;Secure 헤더 추가 Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure </VirtualHost>
Header edit 를 사용하면 지정된 헤더와 일치하는 패턴을 만날 경우 헤더에 특정 값을 추가할 수 있으며 위 예제는 모든 Set-Cookie 헤더뒤에 HttpOnly;Secure 를 추가하도록 합니다.
이제 정상 설정 여부를 확인하기 위해 curl 명령어를 사용하여 서버의 HTTP 응답 헤더를 살펴 봅시다.
$ curl -I -L www.secure.com/cookie.php
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips PHP/7.0.20
X-Powered-By: PHP/7.0.20
Set-Cookie: TestCookie=qwe; expires=Wed, 28-Jun-2017 03:47:25 GMT; Max-Age=3600;HttpOnly;Secure
위와 같이 헤더가 추가되어 나오면 정상적으로 설정된 것입니다.
php.ini 에 추가하려면 아래와 같이 하세요.
session.cookie_httponly = True
X-Frame-Options
클릭 재킹(Clickjacking) 은 클릭과 하이재킹의 합성어로 웹 사용자가 보고 있는 페이지에 악의적인 것을 삽입하여 클릭하게 속이는 해킹 기법으로써 잠재적으로 공격자는 비밀 정보를 얻어내거나 피해자 컴퓨터에 대한 제어를 획득할 수 있게 됩니다.
특히 HTML 의 외부 사이트에 있는 문서를 현재 페이지에 포함시켜서 보여줄 수 있는 <IFrame> 태그는 보안적으로 취약하므로 웹 서비스 개발시 제외하는게 좋습니다.
브라우저 단에서는 클릭재킹을 방지하기 위해 X-Frame-Options HTTP 헤더를 설정하여 보안을 강화할 수 있습니다. 설정할 수 있는 값은 3개이며 다음과 같은 의미를 갖게 됩니다.
- DENY: IFrame 에 있는 소스를 렌더링을 하지 않으므로 클릭 재킹을 방지할 수 있습니다. 단 기존 소스에 IFrame 을 사용한 부분이 있다면 작동하지 않으므로 해당 부분을 재개발해야 합니다.
- SAMEORIGIN: IFrame 을 사용한 원본 리소스와 IFrame 으로 삽입된 원격지 리소스가 동일한 Origin 일 경우에만 렌더링을 합니다. 동일 사이트내에 IFrame 을 사용한 경우 SAMEORIGIN 으로 설정해야 오작동을 하지 않습니다.
- ALLOW-FROM: 이 키워드 뒤에 허용할 URL 을 적어주면 해당 URL 에 있는 리소스만 포함할 수 있습니다.
웹 서버에서는 다음과 같이 설정하면 됩니다.
apache httpd
## IFrame, Object 불허 Header always set X-Frame-Options DENY ## 동일 오리진만 허용 Header always set X-Frame-Options SAMEORIGIN ## app.secure.com URL 만 허용 Header always set X-Frame-Options ALLOW_FROM https://app.secure.com
nginx
nginx 는 http 블록에 추가해 주면 됩니다.
http { ## IFrame, Object 불허 add_header X-Frame-Options DENY; ## 동일 오리진만 허용 add_header X-Frame-Options SAMEORIGIN; ## app.secure.com URL 만 허용 add_header X-Frame-Options ALLOW_FROM https://app.secure.com;
정상적으로 설정했다면 웹 서버를 재구동한 후에 콘솔에서 curl 을 통해서 헤더의 설정 여부를 확인합니다.
$ curl -L -I https://secure.com
X-Content-Type-Options
브라우저는 렌더링을 빨리 하기 위해 컨텐츠 타입을 미리 파싱해서 실제 컨텐츠 타입을 추측하는 기능이 있습니다. 이를 이용하여 잘못된 MIME 형식을 포함하여 HTTP 응답을 보내서 공격을 할 수 있습니다.
X-Content-Type-Options 헤더에 "nosniff" 를 설정해서 전송할 경우 브라우저는 잘못된 MIME 형식이 포함된 응답을 거부하므로 보안이 강화됩니다.
httpd
Header always set X-Content-Type-Options nosniff
nginx
add_header X-Content-Type-Options nosniff;
X-XSS-Protection
IE와 Chrome 브라우저가 지원하며 특정 유형의 XSS(cross site script)공격)을 차단해 줍니다.
apache httpd 는 Header 지시자로 보안 관련 헤더를 설정하면 됩니다.
Header always set X-Frame-Options DENY Header always set X-Content-Type-Options nosniff Header set X-XSS-Protection "1; mode=block"
nginx 는 add_header 지시자로 설정합니다.
add_header X-XSS-Protection "1; mode=block";
iframe 을 사용하여 서비스하는 페이지가 있을 경우 "X-Frame-Option: Deny" 헤더가 설정되면 제대로 동작하지 않습니다.
Content-Security-Policy
Cache-Control
브라우저에서 사용 이력에 대해 cache 를 남기면 공격자가 브라우저 히스토리를 악용할 수 있기 때는 문제가 있습니다.
하지만 cache 를 남기지 않는다면 속도가 느려져서 성능이 떨어지는 사이드 이펙트가 있습니다.
보안성을 충족하고 속도가 느린 문제를 해결하기 위해 관리자 URL 등 중요한 특정 용도의 사이트나 URL 을 대상으로 캐시를 남기지 않도록 Cache-Control 태그를 설정해 주는 게 좋습니다
Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0
Ref
- https://geekflare.com/httponly-secure-cookie-apache/
- https://unix.stackexchange.com/questions/306463/nginx-add-secure-flag-to-cookies-from-proxied-server
- https://developer.mozilla.org/ko/docs/Web/HTTP/Cookies
- http://nisam.tistory.com/8
- https://github.com/aidantwoods/SecureHeaders
- https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#tab=Headers