[여기보기] 적에게 내 WAS의 디렉터리와 파일을 알리지 말라, WAS 디렉터리 인덱싱 및 상위 디렉터리 접근 제한

🧐 | 2023-05-25

[여기보기]는 “여기서 보안의 기본을 챙기고 가자”의 약자로, 개발 과정에서 꼭 최소한으로 챙기면 좋을 보안 기초 설정을 앞으로 하나씩 공유할 예정입니다. 기초 내용이 주를 이루겠지만, 혹시라도 빼먹고 계신 것이 없는지 가끔 한 번씩 둘러봐 주세요.

안녕하세요, 넷마블 보안실 보안개발팀 이지연입니다.

업무에 필요한 자료를 찾다 보면 가끔 웹 브라우저에서 윈도우의 파일 탐색기처럼 폴더나 파일을 나타내는 웹 페이지를 만날 수 있습니다. 예를 들어 우분투 리눅스나 아파치 HTTP 서버는 이전 버전을 배포할 때 디렉터리 구조의 웹페이지를 제공합니다.

그런데 이러한 디렉터리 구조의 웹페이지가 노출돼도 괜찮을까요? 우분투 배포판이나 아파치 HTTP 서버처럼 접근 권한을 잘 관리하면 원하는 배포판 이미지를 편리하게 찾을 수 있습니다. 하지만 접근 권한을 잘못 관리하면 자칫 노출되면 안 되는 상위 디렉터리에 접근하게 되거나 유출되면 안 되는 자료가 노출되는 보안 사고가 발생할 수 있습니다. 이러한 상황을 디렉터리 인덱싱 보안 취약점이라고 합니다.

공개적으로 배포해야 하는 파일이 아주 많은 서비스가 아니라면 WAS의 디렉터리 구조는 노출하지 않아야 합니다. 이번에는 WAS에서 디렉터리 인덱싱 취약점을 노출하지 않는 방법과 혹시 노출해야 하더라도 상위 디렉터리에 이동 제한을 설정해 접근할 수 없도록 설정하는 방법을 살펴보겠습니다.

디렉터리 인덱싱 취약점 해소하기

보통 디렉터리 인덱싱(Directory Indexing)이 활성화되어 있을 경우, WAS의 구조뿐만 아니라 공개되면 안 되는 백업 파일이나 소스 파일 등이 노출될 수 있습니다. 이러한 가능성 때문에 WAS에서는 앞 우분투나 아파치 HTTP 서버의 예처럼 필요한 상황이 아니라면 디렉터리 인덱싱을 사용하지 않는 것을 원칙으로 합니다.

조치 방안

WAS별로 디렉터리 인덱싱의 취약점을 해소하는 방법은 다음과 같습니다.

IIS 7.0~8.0

[윈도우] + [R] 키를 입력해 ‘실행’ 창을 연 후 ‘InetMgr.exe’를 입력하고 [확인] 버튼을 클릭합니다. IIS 관리자가 실행되면 왼쪽 창에서 [사이트] → [Default Web Site]를 선택한 후 오른쪽 [Default Web Site 홈]에서 [디렉터리 검색]을 더블 클릭합니다.

[디렉터리 검색] 설정 화면이 열리면 각종 항목을 설정할 수 있도록 활성화되었는지 확인합니다. 만약 활성화되었다면 오른쪽 [작업] 영역의 [사용 안 함]을 클릭해 디렉터리 인덱싱을 사용하지 않도록 합니다.

디렉터리 검색의 각종 항목 설정이 비활성화되어 있고 오른쪽 [작업] 영역 위에 ‘디렉터리 검색을 사용할 수 없습니다’라는 메시지를 볼 수 있다면 디렉터리 인덱싱을 사용할 수 없도록 설정된 것입니다. 설정을 그대로 유지합니다.

아파치 HTTP 서버

설정 파일에 있는 디렉터리 인덱싱 관련 설정을 삭제하거나 주석 처리해야 사용합니다. 다음 설정 파일 위치를 참고해 vi 명령어로 아파치 HTTP 서버의 디렉터리 인덱싱 설정을 확인합니다.

설치 방법별 아파치 HTTP 서버의 설정 파일 위치는 다음과 같습니다.

  • 아파치 HTTP 서버 컴파일 설치: [Apache2 Dir]/conf/httpd.conf
  • 아파치 HTTP 서버 apt 설치: /etc/apache2/apache2.conf
  • 아파치 HTTP 서버 yum 설치: /etc/httpd/conf/httpd.conf
<Directory /var/www/>
        # 기존 설정
        # Options Indexes FollowSymLinks

        # 변경 설정
        Options FollowSymLinks

        AllowOverride None
        Require all granted
</Directory>

톰캣

web.xml 파일 안에서 <param-name>listings</param-name>이라는 설정 아래의 <param-value> 설정이 false인지 확인해야 합니다. 만약 true라면 false로 바꿔주어야 합니다. vi 명령어로 디렉터리 인덱싱 설정을 확인합니다.

설치 방법별 톰캣의 web.xml 파일 위치는 다음과 같습니다.

  • 톰캣 다운로드 설치: [Tomcat Dir]/conf/web.xml
  • 톰캣 apt 설치: /etc/tomcat버전번호/web.xml
  • 톰캣 yum 설치: /etc/tomcat/web.xml
<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <!-- 아래 부분의 설정이 true면 false로 변경 -->
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

NGINX

NGINX는 보통 디렉터리 인덱싱 관련 설정을 넣지 않아 비활성화하는 것이 기본값입니다. 그런데 autoindex라는 설정의 값에 따라 디렉터리 인덱싱이 활성화된 상태일 수도 있습니다. nginx.conf 파일 안에서 autoindex 설정이 있고 on으로 설정되었다면 off로 변경하기 바랍니다.

설치 방법별 톰캣의 web.xml 파일 위치는 다음과 같습니다.

  • NGINX 컴파일 설치: [NGINX Dir]/nginx.conf
  • NGINX 패키지 관리 도구: /etc/nginx/nginx.conf
autoindex off;

참고로 패키지 관리 도구로 NGINX를 설치했다면 nginx.conf 파일뿐만 아니라 /etc/nginx/sites-available/default 파일에도 autoindex라는 설정과 해당 값이 어떻게 되어 있는지 확인하기 바랍니다.

설정 확인

설정을 마치면 웹 서버 루트 디렉터리 아래의 디렉터리나 파일에 접근할 수 있는지 확인해 보기 바랍니다. 403 Error가 나타나야 합니다.

상위 디렉터리 접근 막기

디렉터리 인덱싱을 사용해야 할 상황이라면 하위 디렉터리에서 상위 디렉터리로 이동하는 것이 가능할 수 있습니다. 그럼 악의적인 목적이 있는 사용자는 하위 디렉터리에 접속해 상위 디렉터리로 이동한 후 WAS에 문제를 발생시킬 수 있습니다. 따라서 상위 디렉터리의 접근을 제어하는 방법을 사용해야 합니다.

조치 방안

보통 상위 디렉터리 접근을 막는 방법은 기본적으로 디렉터리 인덱싱을 허용하지 않는 상태에서 원하는 특정 디렉터리만 디렉터리 인덱싱을 허용하도록 만드는 것입니다. 그런데 상위 디렉터리에 접근할 때 필요한 추가 인증 체계를 구현해서 접근시켜야 할 수도 있습니다. 즉, 상위 디렉터리에 이동 제한을 설정하는 것입니다.

IIS 7.0~8.0

IIS와 ASP를 사용할 때는 ASP 페이지에서 ‘../’ 표기법을 사용해 현재 디렉터리의 상위 경로를 허용하지 않는 방식으로 상위 디렉터리의 접근을 막습니다.

[윈도우] + [R] 키를 입력해 ‘실행’ 창을 연 후 ‘InetMgr.exe’를 입력하고 [확인] 버튼을 클릭합니다. IIS 관리자가 실행되면 왼쪽 창에서 [사이트] → [Default Web Site]를 선택한 후 오른쪽 [Default Web Site 홈]에서 [ASP]를 더블 클릭합니다.

오른쪽 창에 ASP 관련 속성 창이 열리면 [동작] → [부모 경로 사용]을 선택한 후 설정값이 false인지 확인합니다. 만약 true로 설정되었다면 false로 변경합니다.

아파치 HTTP 서버

아파치 HTTP 서버의 디렉터리 설정 관련 항목 중 AllowOverride라는 항목이 있습니다. 이는 디렉터리에 어떻게 접근을 허락할 것인지 결정하는 것입니다. 보통 디렉터리 인덱싱을 비활성화하는 None으로 설정되는데 이를 AuthConfig로 바꿔줍니다.

여기에서는 간단한 ID와 PW를 입력하는 추가 인증을 통해 상위 디렉터리에 접근할 수 있도록 하겠습니다. 예를 들어 ‘웹 주소/reference/sdk’라는 디렉터리의 상위인 ‘reference’ 디렉터리로 이동할 때 접근 제한을 걸겠다고 가정해 보겠습니다. 아파치 HTTP 서버의 설정 파일을 다음처럼 변경합니다.

# 상위 디렉터리
<Directory /var/www/html/reference/>
        # Indexes가 설정되어 있어야 합니다.
        Options Indexes FollowSymLinks

        # AllowOverride를 None에서 AuthConfig로 변경합니다.
        AllowOverride AuthConfig
        Require all granted
</Directory>

# 하위 디렉터리
<Directory /var/www/html/reference/sdk>
        # Indexes가 설정되어 있어야 합니다.
        Options Indexes FollowSymLinks

        # AllowOverride를 None에서 AuthConfig로 변경합니다.
        AllowOverride AuthConfig
        Require all granted
</Directory>

다음으로 상위 디렉터리인 reference 디렉터리에서 vi .htaccess 명령을 실행한 후 다음 설정 내용을 입력합니다.

AuthName "Directory Auth" 
AuthType Basic

# account 대신 임의의 디렉터리 이름을 정해도 상관없음.
AuthUserFile [Apache Dir]/account/.auth
Require valid-user

그리고 ‘[Apache Dir]/account/’를 생성합니다. htpasswd 명령어를 이용해 간단한 ID와 비밀번호를 설정한 후 아파치 HTTP 서버를 재시작합니다.

$ mkdir -p [Apache Dir]/account/

# [Apache Dir]/account/.auth까지는 .htaccess 파일의 AuthUserFile 설정과 경로가 같아야 함.
$ htpasswd -c [Apache Dir]/account/.auth [원하는 ID]
New password:
Re-type new password:
Adding password for user [원하는 ID]

$ service apache2 restart

이제 ‘웹 주소/reference/sdk’에 먼저 접속해 봅니다.

정상적으로 접속되었다면 [Parent Directory]를 클릭해 상위 디렉터리로 이동합니다. 다음과 같이 로그인 창이 열리면서 상위 디렉터리에 접근이 제한됩니다.

로그인을 완료하면 해당 상위 디렉터리를 확인할 수 있습니다.

톰캣

톰캣은 사용자 정의 디렉터리 인덱싱을 이용해 노출하기 원하는 디렉터리 인덱싱만 할 수 있게 만들어 상위 디렉터리 접근을 막습니다. 보통 사용자 정의 디렉터리 인덱싱 목록을 지정하는 xslt 파일을 만들고 해당 파일 안 내용에 따라 접근을 제어합니다. 이때 상위 디렉터리 접근을 허용하거나 허용하지 않도록 설정할 수 있습니다.

<param-name> 속성값으로는 모든 디렉터리 인덱싱에 사용하는 globalXsltFile, 컨텍스트별 디렉터리 인덱싱에 사용하는 contextXsltFile, 디렉터리별 디렉터리 인덱싱에 사용하는 localXsltFile을 선택할 수 있습니다.

vi 명령어로 web.xml 혹은 tomcat-web.xml 파일을 열고 <param-name>디렉터리 인덱싱 속성값</param-name> 설정을 정의합니다. 그리고 아래 <param-value> 설정값으로 허용하려는 디렉터리 경로를 설정합니다. 예를 들면 다음과 같습니다.

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <!-- 아래 부분의 설정이 false면 true로 변경 -->
        <param-value>true</param-value>
    </init-param>
    <!-- 사용자 정의 디렉터리 접근 설정 예 -->
    <init-param>
        <param-name>localXsltFile</param-name>
        <param-value>/WEB-INF/customDriectory.xslt</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

더 자세한 내용 및 xslt 파일의 설정 예는 아파치 톰캣 문서의 Default Servlet Reference를 참고하기 바랍니다.

NGINX

NGINX는 location 설정에 노출하기 원하는 디렉터리를 설정한 후 autoindex 설정을 이용해 해당 디렉터리 인덱싱만 할 수 있게 만듭니다. nginx.conf 혹은 /etc/sites-available/default 파일에 다음 예와 같이 설정합니다.

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # 중간 생략

        root /var/www/nginx/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        # 상위 디렉터리에는 403 혹은 404를 설정해 접근 막기
        location /reference {
                return 404;
        }

        # 하위 디렉터리에는 autoindex on; 설정으로 디렉터리 인덱싱 허용
        location /reference/sdk {
                autoindex on;
        }

        # 이후 생략
}

또한 추가 인증으로만 접근을 허용하려면 auth_basic 설정과 auth_basic_user_file 설정을 이용합니다. 역시 nginx.conf 혹은 /etc/sites-available/default 파일에 다음과 같이 설정합니다.

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # 중간 생략

        root /var/www/nginx/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        # 상위 디렉터리에는 403 혹은 404를 설정해 접근 막기
        location /reference {
                autoindex on;

                auth_basic "RESTRICTED ACCESS";
                auth_basic_user_file /etc/nginx/account/.htpasswd;
        }

        # 하위 디렉터리에는 autoindex on; 설정으로 디렉터리 인덱싱 허용
        location /reference/sdk {
                autoindex on;
        }

        # 이후 생략
}

다음으로 아파치 HTTP 서버와 마찬가지로 [NGINX Dir]/account/ 디렉터리를 생성합니다. htpasswd 명령어를 이용해 간단한 ID와 비밀번호를 설정한 후 NGINX 서버를 재시작합니다.

$ mkdir -p [NGINX Dir]/account/

# [NGINX Dir]/account/.htpasswd까지는 auth_basic_user_file 설정과 경로가 같아야 함.
$ htpasswd -c [NGINX Dir]/account/.htpasswd [원하는 ID]
New password:
Re-type new password:
Adding password for user [원하는 ID]
$ service apache2 restart

이제 ‘웹 주소/reference/sdk’에 먼저 접속해 봅니다.

정상적으로 접속되었다면 ‘../’를 클릭해 상위 디렉터리로 이동합니다. 다음과 같이 로그인 창이 열리면서 상위 디렉터리에 접근이 제한됩니다.

로그인을 완료하면 해당 상위 디렉터리를 확인할 수 있습니다.

디렉터리 인덱싱은 조심해서 허용하자

이 글을 작성하면서 직접 각 WAS의 기본 설정을 확인해 보니 아파치 HTTP 서버를 제외하면 보통 디렉터리 인덱싱을 막아 놓는 편이었습니다. 그래서 사실 디렉터리 인덱싱은 크게 신경 쓸 필요 없다는 인식을 갖는 분도 있을 것입니다. 하지만 취약점을 노리는 사람은 집요한 성격을 지녔을 때가 많으니 방심은 금물입니다.

디렉터리 인덱싱은 보통 사용하지 않겠다는 기본 정책이 있다면 처음 서버 환경 설정에서 해당 설정 여부를 잘 확인해 두면 비교적 안심해도 되는 부분에 속합니다. 오늘은 서비스에서 불필요하게 열린 디렉터리 인덱싱이 있는지 확인해 보면 어떨까요? 여러분의 WAS가 오늘도 한 걸음 더 안전해졌기를 바라며 글을 마칩니다.