본문 바로가기

Tip&Tech/Server

[팁] 웹서버 보안을 위한 툴, ModSecurity 적용하기!

얼마전 오픈소스를 이용해 개발을 하다가 좀 황당(?)한 경험을 했습니다.

PHP 명령어 중 하나인 urlencode()를 이용해 URL을 전달[각주:1]할 때, 해당 URL을 제대로 인식하지 못하는 문제가 발생한 것입니다. 좀 더 정확하게는 "403 Forbidden" 메세지가 출력되었습니다.

처음에는 htpasswd 때문에 발생한 오류인가 했는데, htpasswd 설정을 해제해도 결과는 마찬가지였습니다.

이 문제 때문에 한참을 끙끙대다가 구글 검색을 이용했는데요... 구글신은 단 한 번의 검색으로도 만족스러운 결과를 보여주더군요... 역시, 구글!!!



아래는 구글 검색으로 찾은 페이지의 질문 내용입니다. 이 분의 증상도 저와 거의 유사하더군요...
I had implemented google Open id login my site and it worded perfectly.... Afterwards i moved to hostagtor.. now this url shows a 403 even if i delete my htaccess file. what could be the probelm?
"http://www.clips4u.info/final.php?openid.ns=http%3A%2F%2Fgoogle.com"

all urls of this form shows 403



그리고, 그 밑에는 친절하게도 아래와 같은 답변이 달려있었습니다.
OK, you are facing the same problem that I had few weeks back. (i too host with HostGator)
Some hosting companies disable embedding url parameters in the hosted site's url.
for example:
You can use: http://mysite.com/index.php?id=Google
But NOT
http://www.mysite.com/index.php?id=h...www.google.com

This is disabled due to the mod_security been enabled from the server end.

You can contact HostGator live chat and request them to white flag the specific url where you intend to use domain address in url parameter.

Hope this works.



아하! mod_security 라는 놈이 문제의 원인이었나 봅니다.
그러고보니 Apache를 설정하면서 이 부분을 본 기억이 납니다. ^^;

서둘러 httpd.conf 파일을 열어보니 mod_security 관련 설정이 아래와 같이 보이더군요...
<IfModule mod_security.c>
    include /usr/local/httpd2/conf/security.conf
</IfModule>



이 후, 메뉴얼을 검색해 mod_security의 주요 기능 중 하나가 "한 웹서버에서 다른 곳의 링크[각주:2]를 전달할 때 (보안상) 페이지 출력을 차단하는 것"이라는 사실을 확인할 수 있었습니다.

또한, 검색을 통해 특정 디렉토리(오픈 소스)의 mod_security 설정만 해제하는 방법도 찾을 수 있었는데요... 아래 소스에서 "/home/open_source" 가 mod_security를 해제할 디렉토리의 절대 경로이고, SecFilterInheritance Off가 실제 설정부분입니다.
<Directory /home/open_source>
    SecFilterInheritance Off
</Directory>

결과적으로는 단 3줄의 설정으로 이 문제를 해결할 수 있었습니다만, 문제의 원인을 모르니 정말 답답하기 이를데가 없더군요...



한 가지 재미있는 사실은 mod_security가 단순히 다른 도메인의 URL만 차단하는 것이 아니라 urlencode()로 변환된 URL도 (다른 URL로 인식해) 차단한다는 점이었습니다. PHP에서 특정 URL에 urlencode()를 쓸 경우 :/같은 특수문자를 url 타입으로 자동 변환하게 되는데... 이렇게 변환된 URL을 다른 것으로 인식하는 문제가 있는 것이죠...

예를 들어, http://blog.missflash.com을 urlencode()로 변환하면 http%3A%2F%2Fblog.missflash.com와 같이 바뀌게 되는데[각주:3], mod_security 설정에서는 http://blog.missflash.com와 http%3A%2F%2Fblog.missflash.com를 서로 다른 URL로 인식하기 때문에 링크를 차단하게 되는 것입니다.



혹시, mod_security 설정에서 이 부분을 해결하는 방법이 있을지는 모르겠습니다만... 그렇지 않다면, 조금 문제가 있을 것 같습니다.(사용에 약간의 불편이 있을 뿐이지, 보안상으로는 더 좋습니다. ^^;)
  1. GET 방식을 이용했습니다. [본문으로]
  2. 여기에 한 가지 모순(오류)이 있었습니다. [본문으로]
  3. :가 %3A로 /가 %2F로 바뀌었습니다. [본문으로]