회사에서 바이브 코더들과 많이 일하다 보니 유지보수에 대해 생각하게 됐어요. 소프트웨어는 출시한 뒤에도 돌봐야 하고, 패키지는 낡아 가고, 취약점은 계속 발견되는데, AI로 막 만들기 시작한 때에는 이런 걸 떠올리지 않기 쉬워요.
그러다 같은 생각을 제 프로젝트에도 적용해야겠다는 걸 깨닫고 git 기록을 살펴봤어요. 꽤 많은 걸 찾았는데, 예상했던 것들은 아니었어요. 그리고 그중 하나는 제가 확인한 그날까지도 열려 있었어요.
그러니 이 글은 더 이상 다른 사람들이 잊는 것에 대한 글이 아니에요. 제 이야기예요.
보안 권고 하나, 앱 세 개
10월 14일, Next.js가 치명적(critical) 취약점 두 개와 심각도 높음(high) 취약점 한 개에 대한 수정을 공개했어요. 여기서 '치명적'은 원격 코드 실행을 뜻해요. 즉, 특정 조건에서 인터넷의 낯선 사람이 로그인 없이 내 서버에서 자기 코드를 실행할 수 있다는 말이에요. 수정은 16.4.1 버전에 들어갔어요.
저는 Next.js로 앱 세 개를 운영해요. 모두 AI 코딩 도구로 만들었고, 책임자도 저 한 사람으로 같아요. 이렇게 됐어요.
| 앱 | 코드가 패치된 버전으로 옮겨간 날 | 보안 권고 후 경과 | 프로덕션 반영 |
|---|---|---|---|
| chandlernguyen.com | 10월 18일 | 4일 | 10월 18일 |
| DIALØGUE(다이얼로그) | 10월 29일 | 15일 | 10월 29일 |
| Prova | 11월 3일 | 20일 | 11월 3일 |
11월 3일에 확인했을 때 Prova는 5월부터 쓰던 Next.js 16.2.6에 여전히 고정되어 있었고, 프로덕션도 그 버전으로 돌고 있었어요. pnpm audit --prod를 돌리니 치명적 보안 권고가 5개 나왔고, 전부 Next.js에 있었어요.
이 숫자는 제가 실제로 찾은 것보다 나쁘게 들리니까 공정하게 말할게요. AI 도구와 함께 하나씩 살펴보니 치명적 항목의 대부분은 Prova에 해당하지 않았어요. use cache 함수가 없고, Windows에서 돌지 않으며, 공격자가 제어할 수 있는 입력이 next/og 코드에 닿는 경로도 찾지 못했어요. 이미지 최적화 관련 항목도 Vercel에서는 아마 해당하지 않겠지만, 이건 플랫폼의 동작을 보고 추론한 것이고 Vercel이 그렇게 밝힌 내용은 찾지 못했어요. 분명히 해당한 건 Server Actions의 심각도 높음 서비스 거부 문제였어요. 누군가 앱을 방해할 수 있었다는 뜻이고, 이 문제는 패치할 때까지 남아 있었어요.
저는 같은 날 프로덕션을 Next.js 16.4.5로 옮겼어요. audit 결과는 치명적 5개에서 0개가 됐고, 심각도 높음도 대부분 사라졌어요. 남은 건 Next.js 밖에 있고 아직 처리해야 해요. 그러니 나아지긴 했지만 깨끗하진 않아요.
이 중 어느 것도 좋은 유지보수라고 부를 수 없어요. 최악의 보안 권고들이 Prova를 대체로 비껴간 건 우연히 그렇게 만들어졌기 때문이지, 누가 확인했기 때문이 아니에요. 그건 운이고, 제가 그걸 아는 것도 마침내 들여다봤기 때문일 뿐이에요.
표의 첫 줄도 제 공을 많이 내세우기는 어려워요. 제 사이트의 10월 18일 커밋은 Next.js 16.1.6에서 올리는 일반적인 툴체인 업그레이드였고, 메시지에 보안 권고 이야기는 없어요. 그냥 타이밍이 좋았던 걸 수도 있어요.
바쁘게 일해도 도움이 안 된 이유
쉬운 설명은 Prova가 방치됐다는 거예요. 어느 정도 맞는 말이기도 해요. 8월과 9월 사이에 커밋 간격이 41일이나 벌어졌으니까요.
하지만 이 설명은 10월에 무너져요. 그달에 Prova 커밋은 175개였어요. iOS, 결제, 이메일, 번역 수정을 내보냈는데 Next.js 버전은 그대로였어요. 10월 30일에는 의존성 유지보수 계획까지 썼어요. 그 문서의 상태 줄에는 이렇게 적혀 있어요. "계획됨, 구현 시작 안 함."
그러니까 활동은 유지보수가 아니에요. AI로 무언가를 만드는 사람에게 이게 가장 중요한 부분이라고 생각해요. 기능을 만들면 바로 피드백이 와요. 버튼을 보고, 클릭하고, 작동하는 걸 볼 수 있어요. 다섯 달 전에 설치한 패키지에 취약점이 발표되면 아무것도 오지 않아요. 앱은 계속 페이지를 내보내고, 테스트는 초록색이고, 빌드는 통과해요. 아무것도 고장 나지 않았고, 바로 그래서 아무도 들여다보지 않아요.
직접 가서 물어봐야만 소리를 내는 화재경보기 같은 거예요. AI 도구는 집 짓는 비용을 크게 낮춰 줘요. 하지만 경보기를 달아 주지는 않아요.
이런 일은 전에도 있었어요. DIALØGUE는 2025년 10월 6일부터 2026년 1월 11일까지 커밋이 없었어요. Next.js와 React의 치명적 취약점인 React2Shell은 12월 초에 공개됐어요. 제 패치 커밋은 1월 11일자로 5주도 더 지난 뒤였고, 지금도 볼 수 있는 가장 오래된 프로덕션 배포 기록은 1월 18일 것이라, 12월에 정확히 무엇이 돌고 있었는지는 말할 수 없어요. 아마 가장 도움이 된 건 저와 아무 상관 없는 일이었을 거예요. Vercel은 모든 고객에게 방화벽 규칙을 적용했다고 하면서도, 패치 대신 그것에 의존하지 말라고 분명히 말하고 있어요.
한 가지는 분명히 하고 싶어요. '바이브 코더'라는 말이 모욕처럼 들릴 수 있으니까요. 저는 체계적인 강의로 코딩을 배웠고, 그중에는 사이버 보안 자격증도 있어요. 이 저장소들에는 테스트와 리뷰 게이트도 있어요. 그런데도 이런 일이 일어났어요. 그래서 저는 이게 초보자의 문제라고 생각하지 않아요. 소프트웨어를 만드는 일이 싸지고 그걸 지켜볼 담당이 아무도 없을 때 기본적으로 벌어지는 일이라고 생각해요.
경보기는 어떻게 생겼나
좋은 소식은 아주 작은 점검 하나가 이걸 많이 바꾼다는 거예요.
10월 27일, 저는 사이트 CI에 pnpm audit --prod를 추가했어요. CI는 코드를 푸시할 때 자동으로 돌아가는 점검 묶음이에요. 10월 28일에 이 점검이 실패했어요. 사이트가 끌어오기만 하고 쓰지는 않던 이메일 렌더링 라이브러리의 보안 권고 때문이었고, 10월 29일에 그 라이브러리를 제거했어요. 이틀이 걸렸고, 저는 아무것도 기억할 필요가 없었어요.
영리한 구석은 전혀 없어요. 누군가, 혹은 무언가에게 들여다보라고 시켜 두기만 하면 돼요.
패키지 업데이트로는 구원받지 못했을 거예요
이 글이 여기서 끝난다면 헛된 안심만 드릴 거예요. 10월에 한 수정 중 더 불편한 것들 일부는 오래된 패키지와 아무 상관이 없었으니까요. 제 제품 안의 실수였어요.
예를 들어 DIALØGUE에서는 이런 일이 있었어요.
- 권한이 높은 데이터베이스 함수를 공개 키만으로 호출할 수 있었고, 로그인한 사용자가 제 백엔드 전용 함수에 닿을 수 있었어요.
- 환불된 팟캐스트가 되살아나서 다시 과금되지 않은 채 완성될 수 있었고, 소수의 팟캐스트에서 실제로 그런 일이 있었어요.
Prova에서는 공개 데이터베이스 역할이 아무도 고르지 않은 권한, 예를 들어 TRUNCATE를 상속받고 있었어요. 플랫폼 기본값에서 온 것이었죠. 앱 경로에서 쓰지는 않았지만, 권한은 거기 있었어요.
버전 업그레이드로는 이 중 어느 것도 고쳐지지 않아요. 이 앱들은 이런 문제를 안은 채 돌아가고 있었고, 여기서도 아무것도 고장 나지 않았어요. 드러난 건 오직 보안 리뷰가 찾아 나섰기 때문이고, 이전에 이 제품들에 했던 보안 리뷰로는 전부 잡아내지 못했어요.
이 중 악용된 게 있었을까요? 모르겠고, 완전히 알아낼 수도 없어요. 제 데이터베이스 로그는 약 90일 전까지만 남아 있고, 문제 중 일부는 그보다 오래됐어요. 제가 볼 수 있는 기간에는 그 함수들을 외부에서 호출한 기록을 찾지 못했어요. 다만 이건 제한된 기간만 다룬 것이고, 아무 일도 없었다는 걸 보여 주지는 않아요. 환불된 팟캐스트를 누가 혹은 무엇이 다시 시작했는지도 알 수 없어요. 제 코드의 재시도가 가장 그럴듯한 추측이긴 해요.
이것도 완전한 목록은 아니에요. 아직 다른 문제들을 해결하는 중이고, 열려 있는 동안에는 설명하지 않을 거예요.
모델 문제는 제 생각과 달랐어요
오래된 AI 모델이 돈을 더 들게 한다고 쓰려고 했어요. 그런데 뒷받침할 수가 없어요. 찾아봤지만 어느 저장소에도 전후 비용 기록이 없으니, 그냥 추측이 될 거예요.
제가 찾은 건 더 이상한 것이었어요. DIALØGUE의 대본 초안과 리뷰 모델은 10월 12일까지 gemini-3.5-flash로 설정되어 있었어요. Google 문서에는 이제 그 엔드포인트가 종료되지 않고 요청을 자동으로 gemini-3.6-flash로 보낸다고 적혀 있어요. 그 라우팅이 언제 시작됐는지 모르니, 어떤 모델이 얼마나 오래 답하고 있었는지 말할 수 없어요. 설정 파일에 모델 이름을 적어도 모델이 고정되지는 않아요.
가격도 움직여요. 제가 10월에 Prova와 DIALØGUE를 옮긴 Gemini 3.8 Flash는 12월 31일까지 입력 토큰 100만 개당 $0.75, 출력 토큰 100만 개당 $3.75로 책정돼 있어요. 2027년 1월 1일부터는 두 배인 $1.50과 $7.50이 돼요. 지난달에야 옮겼고, 이게 제 비용에 어떤 영향을 줄지는 아직 계산해 봐야 해요.
업그레이드에도 위험이 없는 건 아니고, 없는 척하고 싶지도 않아요.
- Ask Sydney(시드니)를 DeepSeek Flash로 바꾼 직후, 모델이 제 코드가 허용하는 것보다 많은 검색 라운드를 원해서 프로덕션에서 질문이 최소 하나 실패했어요.
- Prova의 임베딩을 옮길 때, 지식 베이스 테이블을 비운 뒤 첫 실행들이 실패해서 복구할 때까지 검색 품질이 떨어졌어요.
- 같은 마이그레이션에서 Claude 모델 이름을 Google API로 보낼 뻔한 프로덕션 설정도 발견됐어요.
Prova 마이그레이션을 믿을 수 있게 만든 건 지루한 것이었어요. 변경 전에 기록해 둔 평가가 있었고, 스프린트 리뷰 판단 24개 중 22개가 맞았는데, 변경 후에도 같은 점수가 나왔어요. 그게 없었다면 그저 바라기만 했을 거예요.
애초에 유지보수를 해야 할까요?
가장 어려운 질문은 하마터면 빼먹을 뻔한 질문이에요. 출시한 앱은 모두 주의력으로 계속 내야 하는 작은 구독이고, AI 덕분에 구독을 늘리기가 아주 쉬워졌어요.
STRAŦUM(스트라텀)에서는 다른 선택을 했어요. 서비스를 종료하고 v1을 참고 구현으로 공개했어요. 저장소에는 프로덕션 서비스로 유지보수하지 않는다고 적혀 있고, 보안 파일에는 제가 아는 보안 권고들이 나와 있어요. 거기에는 수정본이 없는 빌드 타임 의존성 문제도 있고, 실질적 위험은 낮다고 평가해 뒀어요. 저는 이게 완전히 정직한 결말이라고 생각해요. 정직하지 않은 쪽은 아무도 지켜보지 않는데 계속 가입을 받는 앱이에요.
월요일에 제가 할 일
AI로 무언가를 출시했고 쓰는 사람이 있다면, 저는 이 목록부터 시작할 거예요. 어느 것도 완벽할 필요는 없어요.
- 오늘 audit을 한 번 돌리세요. 운영 중인 모든 저장소에서
npm audit --omit=dev나pnpm audit --prod를 실행하세요. 그런 다음 AI 도구에게 결과 중 어떤 것이 앱 구조에 해당하는지 물어보세요. 전부 해당하지는 않을 거예요. - 그 점검을 자동으로 만드세요. CI에 넣어서 기억하지 않아도 실패할 수 있게 하세요. 잘 건드리지 않는 앱에는 정기 실행도 함께 쓰세요. 푸시할 때만 도는 점검은 조용한 달에 도움이 안 되니까요.
- 패키지만 보지 말고 권한도 읽으세요. 공개 키만 가지고 계정 없이 누가 무엇을 할 수 있는지 물어보세요. 그리고 짐작하지 말고 로컬 복사본에서 시험해 보세요.
- 기록에서 시크릿을 찾으세요. 진짜 키가 커밋된 적이 있다면 폐기하세요. 그 줄을 지우는 것으로는 부족해요.
- 필요해지기 전에 로그가 얼마나 거슬러 올라가는지 알아 두세요. 무언가 악용됐는지에 답할 수 있느냐가 거기서 결정돼요.
- AI 기능마다 작은 평가를 하나씩 두세요. 좋은 답을 아는 실제 사례 20개만 있어도 모델 변경으로 나빠졌는지 알 수 있어요.
- AI 제공사의 지원 종료와 가격 페이지를 정기적으로 확인하세요. 캘린더에 넣어 두세요. Gemini 3.8 Flash를 쓴다면 1월 1일이 시작하기 좋은 날짜예요.
- 앱마다 유지할지 종료할지 결정하세요. 지켜볼 생각이 없다면 내리거나 그렇다고 말하세요.
이 중 얼마만큼을 에이전트에게 일정대로 맡길 수 있을지는 아직 알아보는 중이에요. 다만 10월 30일에 계획을 쓴 것만으로는 아무것도 패치되지 않았다는 건 알아요.
AI로 무언가를 만들고 있다면, 이미 출시한 걸 마지막으로 확인한 게 언제였고, 무엇을 찾았나요? 정말 궁금해요. 제 것보다 나은 경보기가 있다면 더더욱요.