본문 바로가기
카테고리 없음

AWS 비밀키 노출.. 범인은 NEXT_PUBLIC_? (Next.js 환경변수와 동작원리)

by socialcomputer 2025. 11. 16.

저번에 서버 이전 글에서 얘기했듯이

비용절감 위해 자동으로 ec2, rds를 껐다 킬 수 있도록 만들려고 했다.

람다를 사용해야 했는데

aws lambda 함수가 생성 조회가 아무것도 안됐다 

아무리 서치를 해봐도 나같은 사람이 없었다 

aws 큐엔에이 ai 답변을 보니 이럴 경우엔 support에 문의하라는 답변.

물어본 결과 답변은 " IAM 사용자의 액세스 키와 연관된 문제로, 계정에 과도한 과금이 발생하는 것으로부터 보호하기 위해, 일시적으로 일부 AWS 서비스 사용에 접근을 제한" 한다는 이야기로 시작해 "해당 엑세스 키를 삭제하고 몇가지 점검을 해보아라"로 끝났다.

아차 싶었다

Next.js를 써본 적이 없는데 시크릿키들을 수정해서 배포하다 보니

잘못한 점이 있었나 보다.. 이걸 제일 걱정했었는데ㅜㅜ

하지만 이제 알았으니까!!

그래서 이번엔 Next.js의 NEXT_PUBLIC_ 환경변수와

next, react 의 동작차이를 알아보려고 한다

 

NEXT_PUBLIC_은 "전역 변수"가 아니다

코드를 살짝 보고서 프론트엔드(Next.js)에서 값을 읽어오려면 무조건 변수명 앞에 NEXT_PUBLIC_을 붙여야 한다고 착각했다.

1. NEXT_PUBLIC_ 의  의미

이 접두사가 붙은 환경변수는 Build Time(빌드 시점)에 치환된다. 즉, 브라우저에서 F12(개발자 도구)를 열고 소스를 보면 누구나 제 AWS Secret Key를 볼 수 있게 된다는 것이다..!

2. 접두사가 없는 변수

반대로 NEXT_PUBLIC_이 없는 변수는 오직 Next.js가 실행되는 서버(Node.js 환경)에서만 읽을 수 있다. 브라우저로는 전송되지 않아 undefined로 뜨며 비밀번호나 API Key 같은 민감 정보를 담는 용도라고 한다. 

 

React vs Next.js (브라우저와 서버의 차이)

이 문제를 겪으며 Next.js와 React의 동작 방식 차이를 공부하게 되었다.

React (Client-Side)

사용자의 브라우저에서 모든 코드가 돌아간다.

브라우저는 사용자가 볼 수 있는 공간이므로 리엑트의 코드는 공개돼도 상관없는 정보만 있어야 한다.

Next.js (Client + Server)

React 기반이지만 내부에 Node.js 서버를 품고 있다.

브라우저 영역과 서버 영역이 공존해, 비밀키가 필요한 작업은 next.js서버 영역에서 몰래 처리하고 결과만 브라우저로 던져줄 수 있다. 

 

해결 방안: API Routes를 활용한 프록시(Proxy) 패턴

(gemini의 도움을 받아 해결했다)

src/pages/api/ 아래 있는 모든 파일은 Next.js 프레임워크에 의해 관리되고 돌아간다고 한다. 

그래서 여기에 진짜 서버(Spring/AWS )로 보내는 API가 작성되고

다른 리액트에 있는 api는 next서버에게 '이런 요청을 Spring/AWS로 전달해줘' 하는 역할을 한다. 

react -> next -> spring/aws

 

수정 전

브라우저가 키를 가지고 s3에 접근 

수정 후

브라우저 -> Nest.js서버 (서버에 숨겨진 키 사용) -> AWS/spring 서버

next.js가 중간에서 proxy(중계소) 역할을 해주면서 보안 문제를 해결한 것이다. 

이렇게 되면 브라우저에 더이상 시크릿키가 안보인다.

 

 

느낀 점

NEXT_PUBLIC_이 단순 전역변수인 줄 알았던 것이 문제였다. 

다음에는 비밀키 같이 보안이 중요한 것들은 꼭 보안여부를 한번 더 확인하고 수정해야 겠다.

그렇지만 프론트에서 비밀키 보안을 지키는 방법도 알아보았고

넥스트에 대해서도 공부하는 계기가 되어 좋았다.

댓글