열린 디렉터리 인덱스: 파일 서버가 모든 것을 나열할 때
디렉터리 인덱싱이 활성화되어 있으면 /uploads/ 같은 경로에 방문했을 때 403이나 404 대신 해당 디렉터리의 모든 파일을 탐색할 수 있는 목록이 반환됩니다. 백업 아카이브, 로그 파일, 사용자가 업로드한 콘텐츠가 웹으로 제공되는 디렉터리 안에 누구나 읽을 수 있는 상태로 남아 있는 경우가 많기 때문에 공격자는 이곳부터 살펴봅니다.
무엇인가요
디렉터리 목록(디렉터리 인덱싱이라고도 함)은 디렉터리가 요청되었는데 인덱스 파일이 없을 때 HTML 파일 브라우저를 생성하는 웹 서버 기능입니다. 일부 nginx 설정(autoindex on)과 Apache(Options +Indexes)에서는 기본으로 활성화되어 있으며, 정적 호스팅에는 편리하지만 파일이 공개되어서는 안 되는 곳에서는 약점이 됩니다.
AppSafe는 흔히 잘못 설정되는 경로(/uploads/, /files/, /backup/, /backups/, /logs/, /tmp/)를 확인하고, 디렉터리 목록으로 식별되는 응답을 반환하는 경로를 보고합니다. 열린 디렉터리가 하나만 있어도 발견되리라 예상하지 않았던 데이터가 노출될 수 있습니다.
왜 중요한가요
노출된 디렉터리에는 사용자가 업로드한 파일, 압축된 데이터베이스 덤프, 자격 증명이나 세션 토큰이 담긴 애플리케이션 로그, 배포 후 남은 소스 아카이브 등이 흔히 들어 있습니다. 이를 찾는 데는 인증도 공격 기법도 필요 없고 URL만 입력하면 됩니다.
자동 스캐너는 AppSafe가 확인하는 것과 같은 잘 알려진 경로를 도달 가능한 모든 호스트에 대해 끊임없이 탐색합니다. .sql.gz 덤프가 들어 있는 열린 /backup/ 디렉터리는 사실상 비밀번호 없이 넘겨준 데이터베이스 전체 내보내기입니다.
고치는 방법
사용자가 제어하는 디렉터리를 제공하는 server 또는 location 블록에서 autoindex 디렉티브를 제거하거나 명시적으로 off로 설정하세요.
location /uploads/ {
autoindex off;
# Serve individual files but never list directory contents
}가장 안전한 해결책은 업로드, 백업, 로그를 웹 서버가 전혀 제공하지 않는 디렉터리에 저장하는 것입니다. 애플리케이션은 인증된 라우트를 통해 파일을 읽고 스트리밍하므로 파일 시스템의 원래 경로에는 절대 도달할 수 없습니다.
사용자 업로드나 백업을 public/ 디렉터리에 두지 마세요. 인증을 강제하고 요청된 경로를 정제할 수 있는 API 라우트를 통해 제공하세요.
// app/api/uploads/[filename]/route.ts
import { getSession } from "@/lib/auth-session";
import { readFile } from "fs/promises";
import path from "path";
export async function GET(
_req: Request,
{ params }: { params: { filename: string } }
) {
const session = await getSession();
if (!session) return new Response(null, { status: 401 });
// path.basename prevents directory traversal
const safe = path.basename(params.filename);
const filePath = path.join(process.cwd(), "private-uploads", safe);
const data = await readFile(filePath);
return new Response(data);
}탐색 가능한 파일 인터페이스(미디어 라이브러리, 내부 로그 뷰어 등)가 정말 필요하다면, 경로를 숨기는 데 의존하지 말고 인증으로 보호하세요.
location /logs/ {
autoindex on;
auth_basic "Internal only";
auth_basic_user_file /etc/nginx/.htpasswd;
}자주 묻는 질문
디렉터리 목록은 항상 문제인가요, 아니면 특정 경로에서만 문제인가요?
파일에 민감한 내용이 있다면 어디서든 문제입니다. 인덱싱이 켜진 정적 이미지를 제공하는 공개 CDN은 보통 무해하지만, /logs/, /backup/, /uploads/는 거의 항상 그렇지 않습니다. 공개를 전제로 검토되지 않은 파일이 쌓이기 때문입니다.
디렉터리에 빈 index.html을 넣어서 목록 표시를 막아도 되나요?
그렇게 하면 해당 디렉터리의 목록은 숨겨지지만 모든 하위 디렉터리는 여전히 열려 있습니다. 또한 새 디렉터리를 만들 때 놓치기 쉽습니다. 서버 수준에서 autoindex를 끄면 그 아래 모든 것을 포괄하는 확실한 설정 수준의 해결책이 됩니다.
AppSafe는 열린 디렉터리 인덱스를 어떤 심각도로 보고하나요?
중간입니다. 목록 자체는 침해가 아니라 침해로 가는 경로입니다. 데이터베이스 덤프가 들어 있는 탐색 가능한 /backup/ 디렉터리나 인증 토큰이 평문으로 기록된 /logs/ 디렉터리가 있다면 그것만으로도 금세 중간 이상의 심각도가 됩니다.