[실전 security ③] 안전한 웹 서버 프로그래밍

보안, 암호화 2008. 8. 5. 20:12 posted by 무병장수권력자


실전! 개발자를 위한 Security 체크 포인트
③ 안전한 웹 서버 프로그래밍

작성자 : 김문규
최초 작성일 : 2008. 8. 6
* 본 포스트는 SDS e-campus의 '실전 개발자를 위한 Security 체크포인트' 강의 내용을 발췌하여 재구성한 개인적인 학습노트 입니다.

1. 안전한 웹 프로그램 작성 지침

1) 중간페이지가 바로 접속되어서는 안됩니다.

 - 보안이 필요한 모든 페이지에서 세션 검사

2) 중요 정보가 노출되어서는 안됩니다.
 - GET 방식으로 전송되는 모든 데이터는 암호화하여 변조 방지
 - Hidden 필드의 변조 방지
 - 참조 1의 매개 변수 값을 안전하게 보호하는 방법 참조

3) 중요(인증)정보는 평문형태의 Cookie를 사용하면 안됩니다.
 - 참조 1의 매개 변수 값을 안전하게 보호하는 방법 참조

4) 개발자가 아닌 사용자는 HTML tag 입력이 불가해야 합니다.
 - 만일 입력이 꼭 필요한 경우에는 공격의 소지가 없는 일부 태그만을 사용가능 하도록 제한합니다.

5) 사용자ID 및 패스워드는 암호화해서 전송해야합니다.
 - SSL 암호화 (128 bit 이상) 사용
 - ActiveX Control을 이용
 - 자바 스크립트로 구현할 경우에는 replay attack이 가능하지 않도록 주의합니다.

6) 중요한 HTML 소스는 암호화합니다.
 -

사용자 삽입 이미지


2. 맺음말
이번 장은 조금 더 자세한 수준으로 공부하게 된 것 같습니다. 제 생각에는 이 내용을 숙지하고 직접 간단한 예제를 작성해 보아야 하지 않을까 생각됩니다. 저도 일단은 apache를 깔고서 취약점을 공개한 코드랑 아닌 코드랑 비교해 보아야 겠습니다. 시간이 허한다면 이 내용도 추후에 추가토록 하겠습니다.
그럼! 이만!
 

참조 1. 매개 변수 값을 안전하게 보호하는 방법

1) 매개 변수의 암호화
hidden, cookie와 같은 매개변수를 클라이언트에서 서버로 전달할 때 대칭키 방식으로 암호화합니다. 키와 알고리즘은 노출되지 않도록 하고, 키는 Session별로 다르게 하여 (timestamp 등 활용) 동일한 접속이라고 하더라도 접속할 때마다 다르게 전송 합니다.

2) 매개 변수의 조작 여부 확인
또 한가지 방법은 매개변수의 조작여부를 체크하는 것입니다.
hidden, cookie에 변수 하나를 Check 값으로 저장해 (서버→클라이언트)로 내려 갔을 때와 (클라이언트→서버)로 돌아온 값들의 조작여부를 확인합니다. 이런 Check하는 변수에 md5, sha1과 같이 해쉬 알고리즘을 이용하여 체크하는 과정을 체크섬 이라고 합니다. (서버→클라이언트)로 갔던 체크 값과 (클라이언트→서버)로 올라왔을 때 체크 값이 일치하면 정상, 틀리면 변수값 조작이 있었던 것이므로 비정상 에러를 출력하는 것입니다.
예) <input type=hidden name=val1 value="7308022748398">
     <input type=hidden name=val2 value="아무개">
     <input type=hidden name=check
                                 value="q4837ksdafjgjsdg8345arfE78==">
이때 주의해야 할 것은 무슨 알고리즘을 사용하였는지 안다면 쉽게 Check 값도 조작이 가능하다는 것입니다. 그런 경우에 사용 가능한 것이 Salt를 활용하는 것입니다.
변수값1 + 변수값2 + "임의의 값"(Salt)     ->(해쉬 함수)   체크값
위와 같이 소금(Salt)을 쳐 놓으면 소금(Salt)은 서버프로그램에만 들어있기 때문에 체크값을 조작하기란 어려울 것입니다.

사용자 삽입 이미지


참조 2. Cross-Site Scripting 공격이란?

[출처]
XSS(Cross Site Scripting) 취약점에 대해 #3|작성자 지름중독 쭈니아빠
(http://blog.naver.com/jakehong?Redirect=Log&logNo=120003091823)

먼저 XSS를 이용해 공격을 한다는것은 사용자의 입력내용을 포함하는 HTTP요청에 대해 동적으로 HTML을 생성하는 어플리케이션(CGI)이 공격대상이 됩니다. 정적인 웹페이지, 즉 일반적인 HTML로 작성된 웹페이지에서는 이 문제는 일어나지 않습니다.
이해를 돕기위해 간단한 예제를 보겠습니다.

사용자 삽입 이미지
그림 3-1 : 텍스트입력란이 있는 cgi 프로그램
그림 3-1과 같이 텍스트을 입력받는란이 있어 여기에 사용자가 임의의 문자열을 입력한후 "전송하기"버튼을 누르면 사용자의 입력한 문자열을 웹페이지에 출력해주는 cgi 프로그램이 있다고 하면 결과는 다음과 같을것입니다.

사용자 삽입 이미지
그림 3-2 : 사용자가 입력한 문자열을 이용해 동적 HTML페이지를 생성한 결과
간단한 예제지만 이처럼 사용자가 입력한 문자열을 이용해 동적 HTML 출력하는 경우에 XSS취약점공격이 끼어들 가능성이 있는 페이지입니다. 그림 3-2를 웹브라우져의 "소스보기' 메뉴를 이용해서 HTML소스를 확인해보면 다음과 같습니다.
========================================================
<HTML>
<BODY> 
   메세지 : 안녕하세요 jakehong님!
</BODY>
</HTML>
========================================================
그럼 이번에는 그림3-1 화면에서 굵은폰트속성을 나타내는 HTML 태그를 사용하여 "안녕하세요 <B>jakehong</B>님!"이라고 입력해 본다면 결과가 어떻게 나올것 같나요? XSS취약점에 대한 대비가 안되어있는 cgi프로그램이라면 대부분 아래와 같이 "jakehong" 부분이 굵은 글씨로 출력된 페이지를 보게됩니다.
사용자 삽입 이미지
그림 3-3 : jakehong부분이 굵은폰트로 출력된 화면

이 화면의 HTML소스를 보면 다음과 같습니다.
========================================================
<HTML>
<BODY> 
   메세지 : 안녕하세요 <B>jakehong</B>님!
</BODY>
</HTML>
========================================================
사용자가 입력한 "안녕하세요 <B>jakehong</B>님!" 문자열을 입력한 그대로 출력하고자 한다면 "안녕하세요 &lt;B&gt;jakehong&lt;/B&gt;님!" 라고 출력해야 하지만 그 부분에 대한 처리를 해주지 않은것입니다.
그럼 이번에는 입력란에 "<SCRIPT>alert("까꿍!");</SCRIPT>"라고 입력해 보면 아래 그림과 같이 "까꿍!" 이라고 써진 다이얼로그박스가 나타납니다.
사용자 삽입 이미지
그림 3-4 : 입력란에 <SCRIPT>태그를 입력한 결과
HTML소스를 보면
========================================================
<HTML>
<BODY> 
   메세지 : <SCRIPT>alert("까꿍!");</SCRIPT>
</BODY>
</HTML>
========================================================
예상한대로 웹브라우져는 이 입력값을 스크립트라고 해석해 다이얼로그창을 보여줍니다. 예제에서는 단지 다이얼로그창을 띄운거지만 이 외에도 모든 script를  삽입하는것이 가능할 것입니다.
이처럼 웹페이지에 사용자가 임의의 script를 삽입시킬수 있는 문제가 있기 때문에 이를 XSS(Cross Site Scripting)라고 합니다.
예제는 자신이 입력한 스크립트를 자신이 실행하는것이지만 약간만 응용하면 다른사람에 의해 작성된 스크립트를 강제로 실행하게끔 하는것이 가능합니다.
그림 3-4에서 "확인"을 누른후 윈도우창 상단의 URL입력란을 보게되면

사용자 삽입 이미지
그림 3-5 : 그림 3-4 에서 "확인"을 누른후 URL란 확인
 
그림의 글씨가 좀 작아서 다시 쓰겠습니다.
====================================================================================
====================================================================================
이 URL encode 스트링(빨간글자)을 decode하면 이전 페이지에서 사용자가 입력한 <SCRIPT>alert("까꿍!");</SCRIPT>이란 글자가 됩니다.
즉, 이 cgi프로그램은 사용자가 입력한 문자열을 URL뒤에 인자로 추가하여 cgi프로그램에 전달되어 cgi프로그램이 이를 읽어 출력화면의 일부로 웹브라우져에 표시를 하는것입니다.
조금만 더 응용해 보겠습니다. 이번엔 XSS 취약점이 있는 웹싸이트에 다음과 같은 웹페이지를 하나 만듭니다.
===========================================================
<HTML>
<BODY bgcolor="black" link="white">
<A HREF='http://공격자사이트/text_r.asp?str=<script>alert("Merong~") ;</script>'>
여기를 클릭 </A>
</BODY>
</HTML>
===========================================================
사용자 삽입 이미지
그림 3-6 : 다른싸이트에 있는 script를 수행하는 예제
만일 사용자가 해커가 만들어논 이 페이지를 클릭하게 되면
=============================================================================
=============================================================================
해커가 사전에 만들어논 공격자싸이트의 cgi프로그램이 수행되면서 위에서 언급한 스크립트가 실행되는것입니다.
이처럼 공격대상싸이트에 공격자싸이트를 크로스(걸쳐서)시켜서 공격하기 때문에 XSS(Cross Site Scripting)이라고 합니다.