LUCAS.

BLOG · 2026-09-12

정적 사이트를 Cloudflare Pages에 올리면 레포 전체가 공개된다

빌드 과정이 없는 정적 사이트를 Pages에 연결하면 레포에 있는 모든 파일이 그대로 웹에 열린다. 내 포트폴리오에서 내부 문서가 노출되고 있던 걸 발견하고 막은 기록.

포트폴리오 사이트를 검색엔진에 등록하려고 robots.txtsitemap.xml을 만들었다. 크롤러를 불러들이는 작업이니 그 전에 뭐가 공개되고 있는지부터 봤는데, 생각보다 많은 게 열려 있었다.

레포에 있는 건 전부 공개된다

이 사이트는 빌드 과정이 없다. HTML과 CSS, 데이터 파일 몇 개가 전부고 Cloudflare Pages가 GitHub 레포를 그대로 서빙한다. 편해서 좋았는데, 여기에 함정이 있었다. 빌드 산출물 디렉터리가 따로 없으면 레포 루트가 곧 공개 폴더가 된다.

실제로 확인해 보니 이런 것들이 전부 200으로 열렸다.

PUBLISH.md                      200
docs/code-audit-2026-07-02.md   200
publish.sh                      200
capture-shot.sh                 200
.gitignore                      200

PUBLISH.md는 배포 절차 메모였다. 서버 경로, Caddy 설정 위치, 인증서 파일이 어디 있는지가 적혀 있었다. docs/에 있던 건 예전에 받은 코드 점검 문서인데, 이 프로젝트의 알려진 약점 목록이 그대로 들어 있었다.

비밀번호가 샌 건 아니었다

다행히 토큰이나 키 같은 실제 값은 없었다. 커밋 이력 전체를 훑어서 확인했다. 스크립트들은 ~/.secrets/ 아래 파일을 참조만 하고 값을 품고 있지 않았다.

그래도 문제는 문제다. 서버 구조와 약점이 적힌 문서가 검색엔진에 색인되면, 침입을 시도하는 쪽에서는 정찰을 대신 해준 셈이 된다.

막는 방법 두 가지

가장 확실한 건 사이트 파일만 public/ 같은 폴더에 넣고, Pages의 빌드 출력 디렉터리를 그 폴더로 바꾸는 것이다. 그러면 나머지는 애초에 배포에 포함되지 않는다.

다만 이건 대시보드 설정을 건드려야 하고, 순서를 잘못 잡으면 사이트가 잠깐 죽는다. 설정을 먼저 바꾸고 파일을 옮겨야 무중단으로 넘어간다.

그래서 나는 두 가지를 섞었다.

/publish.sh       /  301
/capture-shot.sh  /  301
/gen-showcase.cjs /  301
/.gitignore       /  301

예상이 틀렸던 부분

처음엔 _redirects가 안 먹을 거라고 봤다. 정적 파일이 실제로 존재하면 리다이렉트보다 파일이 우선일 거라고 생각했기 때문이다.

배포해서 확인해 보니 리다이렉트가 이겼다. 301이 나가고 본문은 비어 있었다. _redirects 파일 자체도 서빙되지 않아서(404), 어떤 경로를 가렸는지 광고하지도 않았다.

추측으로 넘어갔으면 "아마 안 될 것"이라고 적어두고 지나갔을 일이다. 한 번 배포해서 확인한 게 나았다.

정리

빌드 없는 정적 사이트는 편하지만, 편한 만큼 레포에 뭘 넣는지가 곧 공개 여부를 결정한다. 깃허브 레포가 비공개라고 해서 배포된 사이트까지 비공개인 건 아니다. 이 둘은 별개다.

지금은 레포 루트에 새 스크립트나 설정 파일을 추가할 때마다 같은 커밋에서 _redirects에 한 줄을 같이 넣는 걸 규칙으로 정해뒀다.

← 다른 글 보기