용어 사전

.env란 — 환경 파일이 유출되면 무슨 일이 일어나는가

.env는 DB 자격 증명, API 키, 암호화 키 등 앱의 시크릿을 한 파일에 모읍니다. 유출되면 무엇이 열리는지, 어디에 두어야 하는지, git 관리와 키 교체로 지키는 법을 다룹니다.

게시 2026-06-07 업데이트 2026-10-06 6분 읽기
이 페이지에서

.env는 매우 편리해 거의 모든 현대 프레임워크가 사용합니다. 하지만 한 번 잘못된 곳에 두면 그 안의 모든 시크릿을 누구나 읽을 수 있게 됩니다. 이것이 무엇인지, 그리고 어떻게 지키는지를 바닥부터 살펴봅니다.

조금 더 자세히

앱에는 "환경마다 바뀌는 값"과 "아무에게도 보이고 싶지 않은 값"이 있습니다: DB 비밀번호, 외부 API 키, 세션을 암호화하는 키. 이것들을 소스에 하드코딩하면 코드를 공유하는 순간 시크릿이 새어 나갑니다.

그래서 이를 하나의 .env 파일에 모아 코드에서 "환경 변수"로 읽습니다. Next.js, Laravel, Rails 등 많은 프레임워크가 이 방식으로 동작합니다.

내용은 한 줄에 '이름=값' 하나씩 쓰는 일반 텍스트입니다(아래 값은 자리 표시용입니다).

APP_ENV=production
DB_HOST=127.0.0.1
DB_PASSWORD=your-db-password-here
PAYMENT_API_KEY=your-payment-api-key-here

설정을 코드 밖에 두는 방식은 웹 앱 설계 지침 "The Twelve-Factor App"으로 널리 퍼졌습니다. 이 지침은 설정이 제대로 분리되었는지 판단하는 기준으로, 자격 증명을 하나도 노출하지 않고 지금 당장 코드베이스를 오픈소스로 공개할 수 있는지를 듭니다. .env는 개발 중에 이 생각을 실천하기 위한 편리한 그릇입니다.

비슷한 것과의 차이

.env와 자주 헷갈리는 것들입니다. 이 중 일부만이 시크릿을 두어도 되는 곳입니다.

이름무엇인가시크릿을 두어도 되나
환경 변수OS나 컨테이너가 실행 중인 프로세스에 넘기는 값된다(운영 환경의 기본)
.env환경 변수를 파일로 모은 것되지만, 공개 디렉터리나 Git에는 절대 두지 않는다
.env.example이름만 나열하고 값은 비운 견본안 된다(커밋하기 위한 파일)
NEXT_PUBLIC_* / VITE_*브라우저용 JavaScript에 박혀 들어가는 변수안 된다(누구나 읽을 수 있음)
시크릿 매니저비밀 값을 보관하는 클라우드 서비스된다. 권한과 감사 로그로 관리

놓치기 쉬운 것은 네 번째 줄입니다. Next.js는 NEXT_PUBLIC_로, Vite는 VITE_로 시작하는 변수의 값을 빌드할 때 브라우저로 보내는 JavaScript에 박아 넣습니다. .env 안에 있더라도 이 접두어가 붙은 변수는 공개됩니다.

왜 "가장 위험한 파일"인가

여러 키가 한 파일에 있기 때문에, 한 번의 노출이 피해를 빠르게 번지게 합니다. "유출된 각 값이 무엇을 여는지" 나열하면 심각성이 분명해집니다.

유출된 값무슨 일이 일어나는가
DB 자격 증명데이터 읽기 / 변조 / 삭제
외부 API 키사칭 사용, 부정 과금
암호화 키(예: Laravel APP_KEY, 서명 키)세션 위조, 사칭 로그인
OAuth 시크릿연동 앱 장악

실제로 .env 노출은 고전적인 사고입니다. → 전 세계에 노출된 .env

실제 사례: 노출된 .env가 노려진다

  • 대규모 갈취 작전(2024): 한 보안 기업의 연구팀은 11만 개 도메인을 노려 웹 서버에 노출된 .env 파일을 수집하고, 그 안의 클라우드 인증 정보로 데이터를 빼낸 뒤 몸값을 요구한 활동을 보고했습니다. 수집된 변수는 9만 개가 넘었고, 그중 약 7,000개가 클라우드 서비스용, 약 1,500개가 SNS 계정용이었습니다. 원인은 클라우드 사업자의 취약점이 아니라, .env를 노출한 조직 쪽의 설정 실수였습니다
  • Vercel(2026년 4월): 내부 시스템에 대한 무단 접근으로 일부 고객의 환경 변수가 읽혔습니다. 값을 다시 표시할 수 있는 분류로 저장된 것들이었습니다 → 상세 기사
  • 공개 저장소(2026년 연구): GitHub에 공개된 54만 건이 넘는 인증 정보가 조사 시점에도 여전히 유효했습니다. 인증 정보를 폐기하지 않으면 파일이나 이력을 지워도 소용이 없습니다 → 상세 기사

첫 번째 사례는 노출된 .env가 사람이 둘러보다가 발견하는 것이 아니라, 자동으로 대량 수집된다는 것을 보여 줍니다. 작은 사이트라서 발견되지 않을 것이라고 가정하지 마세요.

전형적인 유출 = 배치 실수

가장 큰 원인은 "앱 전체를 공개 디렉터리(문서 루트)에 두는 것"입니다. public/만 서빙되어야 할 곳에서 그 상위를 노출하면 .env까지 닿을 수 있게 됩니다.

✗ 위험(앱이 공개 루트에 있음)

public_html/
├─ .env   ← 읽힘!
├─ app/
└─ public/

✓ 안전(앱은 바깥, public만 서빙)

app-root/
├─ .env   ← 닿을 수 없음
├─ app/
└─ public_html/ → public/
앱은 문서 루트 바깥에 두고 public/만 서빙하세요. 그것만으로 .env에 닿을 수 없게 됩니다.

배치 외에도 다음 경로로 유출됩니다.

  • Git에 커밋한다(공개 저장소라면 즉시 공개, 비공개라도 접근 권한이 있는 모두에게 보임)
  • .env.bak, .env.old 같은 백업을 공개 디렉터리에 남겨 둔다
  • .env가 든 채로 컨테이너 이미지나 배포용 zip을 내보낸다
  • 위에서 설명한 대로 NEXT_PUBLIC_ / VITE_ 변수에 시크릿을 넣는다

지키는 법

1

공개 디렉터리에 두지 않기

앱을 문서 루트 바깥에 두고 public/만 서빙하세요. 공유 호스팅의 구체적 절차: 이 가이드.

2

git에 커밋하지 않기

.env*를 .gitignore에 추가하고, 값이 비어 있는 .env.example만 공유하세요.

3

유출되면 전부 교체

확인된 키 하나만이 아니라 — .env에 있던 모든 키를 교체하세요. 전부 보였다고 가정하고 움직이세요.

4

정기적으로 자가 점검

자기 사이트에서 /.env를 열 수 없는지 확인하는 습관을 들이세요.

사이트와 저장소에서 확인하는 방법

자가 점검(본인 소유 도메인에 대해서만)

# 본문이 있는 200이면 노출된 것입니다. 403/404이면 지금은 괜찮습니다.
curl -sI https://yourdomain/.env | head -1
curl -sI https://yourdomain/.git/config | head -1

배포할 때마다 이를 점검하면 배치 실수를 일찍 잡아냅니다.

사이트의 바깥과 저장소의 안쪽을 모두 확인하세요.

  1. 소유를 확인한 사이트라면 사이트 보안 점검이 /.env, /.env.local, /.env.bak 같은 경로를 한 번에 검사합니다
  2. 저장소에서 git log --all --oneline -- .env를 실행해 커밋된 적이 있는지 확인합니다. 무언가 나오면 그 안에 있던 키를 폐기하세요
  3. 설정이나 코드를 시크릿 유출 스캐너에 붙여 넣어 하드코딩된 API 키나 개인 키를 찾습니다(브라우저 안에서 동작)
  4. NEXT_PUBLIC_ / VITE_ 변수 목록을 점검해 빌드된 JavaScript에 시크릿이 들어가지 않는지 확인합니다

본 사이트의 견해: .env를 둘 곳과 키를 폐기하는 방법을 함께 정한다

.env 사고의 대부분은 잘못된 곳에 놓인 파일 하나에서 시작됩니다. 그 뒤에 피해를 키우는 것은 키를 교체하는 절차가 정해져 있지 않다는 점입니다. 본 사이트는 .env를 쓴다면 공개 디렉터리와 Git 밖에 두는 것에 더해, 그 안의 키마다 폐기하고 재발급하는 방법을 미리 적어 두기를 권장합니다. 운영 환경에서는 클라우드 시크릿 매니저나 값을 다시 표시할 수 없는 환경 변수로 옮기면 유출 경로가 더 줄어듭니다.

출처(1차 자료)

  • The Twelve-Factor App, "III. Config" — 12factor.net(설정을 환경 변수에 둔다, 오픈소스 판단 기준)
  • Next.js 문서, "Environment Variables" — nextjs.org(NEXT_PUBLIC_는 빌드 시 JavaScript에 인라인됨, .env 파일을 커밋하지 않기)
  • Vite 문서, "Env Variables and Modes" — vite.dev(VITE_ 변수는 클라이언트 코드에 노출됨)
  • Unit 42(Palo Alto Networks), "Leaked Environment Variables Allow Large-Scale Extortion Operation in Cloud Environments"(2024년 8월 15일) — unit42.paloaltonetworks.com

다음으로 읽기

분류 번호

CWE는 취약점의 원인이 되는 약점의 종류를, MITRE ATT&CK는 공격자의 기법을 분류한 번호 체계입니다. 둘 다 MITRE가 관리하며 취약점 정보와 탐지 규칙 분류에 널리 쓰입니다.

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

Q.env를 git에 커밋해도 되나요?
A

안 됩니다. .env를 .gitignore에 추가하세요. 대신 어떤 키가 필요한지 공유하기 위해 값이 비어 있는 .env.example을 커밋하세요.

Q.env에서 시크릿이 단 하나라도 새면 무엇을 교체해야 하나요?
A

확인된 것 하나만이 아니라 — .env에 있던 모든 키를 교체하세요. 우선순위: 외부 API / OAuth 시크릿 → 암호화 키 → 메일 → DB. 전부 보였다고 가정하고 움직이세요.

Q.env가 유출됐는지 어떻게 확인하나요?
A

브라우저에서 https://yourdomain/.env 를 열어보세요. 내용이 보이면 노출된 것입니다(본문이 있는 200 = 나쁨). 차단되면(403/404) 지금은 괜찮습니다.

Q.env는 무슨 뜻인가요?
A

보통 '닷 엔브'라고 읽습니다. env는 environment(환경)의 줄임말이고, 앞의 점은 Linux와 macOS에서 숨김 파일을 뜻합니다. 파일 내용은 DB_PASSWORD=… 같은 '이름=값' 줄의 목록이며, 앱이 이를 환경 변수로 읽어 들입니다.

QNEXT_PUBLIC_이나 VITE_로 시작하는 변수에 시크릿을 넣어도 되나요?
A

안 됩니다. Next.js(NEXT_PUBLIC_)와 Vite(VITE_)에서는 이 접두어가 붙은 변수의 값이 빌드할 때 브라우저로 보내는 JavaScript에 박혀 들어가, 누구나 읽을 수 있습니다. .env 안에 있다고 해서 비밀이 되는 것은 아닙니다. API 키는 서버 쪽 코드에서만 쓰고 이 접두어를 붙이지 마세요.

Q실수로 .env를 GitHub에 올렸습니다. 어떻게 해야 하나요?
A

먼저 그 안에 있던 모든 키를 폐기하고 재발급하세요. 파일 삭제나 이력 재작성으로는 이미 만들어졌을 수 있는 복사본을 되돌릴 수 없으므로, 삭제보다 폐기가 먼저입니다. 그다음 .env를 .gitignore에 추가하고 이력에서 지우세요.