Moment.js는 더 이상 사용되지 않는가요? 구버전 현황, CVE 및 지원 옵션

지원 종료(EOL)된 PHP용 php2shell 패치(CVE-2026-109618 및 CVE-2026-109619)가 출시되었습니다. 수요가 많아 평소보다 영업팀의 답변이 늦어지고 있으므로, 패치된 패키지를 가장 빠르게 확보하려면 온라인에서 Runtimes용 ELS를 구매하시기 바랍니다 (새 탭에서 열림). 패치 FAQ 읽어보기

이 블로그 글의 AI 요약으로 바로 가기

  • Perplexity를 사용하여 이 게시물을 요약해 주세요
  • Gemini로 이 게시물을 요약해 주세요

주요 내용

  • Moment와 Moment Timezone은 유지보수 단계에 있는 구형 프로젝트이므로, 새로운 작업에서는 대체 솔루션을 사용해야 합니다.
  • 레거시 상태라고 해서 반드시 즉시 제거해야 하는 것은 아니며, 모든 설치 환경이 취약해지는 것도 아닙니다.
  • Moment에서 벗어나는 전환은 구문 문제보다 가변성 및 관대한 구문 분석 문제에서 훨씬 더 자주 발생합니다.
  • 번들 크기 벤치마크가 아니라, 주로 사용하는 시간대 및 구문 분석 방식에 따라 대체할 대안을 선택하십시오.

Moment는 사용자에게 더 이상 이 라이브러리를 사용하지 말라고 공개적으로 밝힌 드문 라이브러리입니다. 이 프로젝트는 2020년에 이미 레거시 상태와 유지보수 모드를 선언했으며, npm 페이지에서는 여전히 새로운 기능을 추가하지 않는 레거시 프로젝트로 표시되고 있습니다. 게다가 Moment Timezone의 README 파일은 한 걸음 더 나아가 대부분의 사용자에게 다른 라이브러리를 선택하라고 권고하고 있습니다. 이는 서류상으로는 지원 종료(EOL)가 아닙니다. 하지만 2.24.0 버전에 묶여 있는 팀에게는 실질적인 문제가 사실상 종말과 다름없습니다. 업스트림에서 수정 사항이 최신 Moment 버전에 반영되지만, 그 오래된 릴리스 버전으로 역포트해 주는 사람은 아무도 없기 때문입니다.

문제는 Moment를 대체하는 것이 단순한 구문 연습이 아니라는 점입니다. Moment의 객체는 가변적이며, 구문 분석 방식도 현대의 대체 라이브러리들이 의도적으로 채택한 엄격한 기준과는 달리 관대하기 때문에, 마이그레이션이 제대로 이루어지지 않으면 컴파일 오류가 아닌 잘못된 날짜로 나타납니다.

Moment는 플랫폼이 준비되기도 전에 문제를 해결했습니다.

Moment.js는 자바스크립트 날짜 처리가 정말로 골치 아팠던 시기에 등장했습니다. 파싱과 서식 지정은 엔진마다 다르게 작동했고, 시간대 계산은 추측에 의존해야 했으며, 헬퍼 라이브러리 없이 날짜 서식을 지정하려면 아무도 맡고 싶어 하지 않는 수동 문자열 조작을 해야만 했습니다. Moment는 이러한 문제를 해결했으며, 그 성능이 워낙 뛰어나 10년 가까이 기본 표준으로 자리 잡았습니다. 이 라이브러리의 오랜 역사를 실패로 간주하는 것은 사실을 뒤집는 것입니다. Moment는 플랫폼이 그 수준에 도달하기 전에 실제 문제를 해결해 냈습니다.

그래서 지금의 상황이 더욱 이상하게 느껴집니다. 버전을 확인하려고 패키지 페이지를 열면, README 파일이 열리면서 이 프로젝트가 유지보수 모드에 있는 레거시 프로젝트라는 경고가 표시됩니다. 그러고 나서 자신의 저장소를 grep으로 검색해 보니, 그중 세 곳에 Moment가 들어 있는 것을 발견하게 됩니다.

“유지보수 모드”라는 표현을 무언가 더 새로운 것으로의 은근한 전환 신호로 해석하기 쉽습니다. 하지만 이는 본질을 놓치는 것입니다. 이는 무엇이 수정되고 무엇이 수정되지 않을지에 대한 선언이며, 일단 그런 관점에서 해석하면, 여러분의 package.json 모양이 달라 보이기 시작한다.

Moment.js는 더 이상 사용되지 않는 기능인가요? 그리고 ‘유지보수 모드’란 무엇을 의미하나요?

엄밀한 의미에서는 아닙니다. 공식적인 지원 종료 일정이 발표된 적도 없고, 프로젝트 종료 커밋도 없습니다. 이 프로젝트는 스스로를 ‘유지보수 단계에 있는 레거시 프로젝트’라고 규정하고 새로운 도입을 자제하도록 권고하고 있는데, 이는 단순히 ‘예’나 ‘아니오’라고 단정 짓는 것보다 더 정확하고 유용한 답변입니다.

유지보수 담당자들은 적용 범위에 대해 명확히 밝혔으며, 2020년 이후 처음으로 2026년 8월에 그 범위를 재조정했습니다. Moment는 여전히 중대한 보안 문제를 해결할 것이며, Moment 타임존 데이터 업데이트는 계속해서 IANA 릴리스를 따를 것입니다. 여전히 사용자에게 직접 노출되는 새로운 기능은 도입하지 않을 것이며, 가변형(mutable) API를 재설계하지도 않을 것입니다. 달라진 점은 적용 범위입니다. 2020년 정책은 번들 크기와 트리 셰이킹에 대한 작업은 물론 버전 3 관련 작업도 모두 배제했습니다. 2026년 업데이트는 그 범위를 확대하여, 유지보수 담당자들이 패키징, TypeScript 선언, 빌드 툴링, 번들 구성 등을 다룰 수 있도록 허용했습니다.

그건 단순한 말이 아니었습니다. 2026년 9월 14일에 출시된 Moment 2.31.0에는 보안 패치, 수많은 버그 수정 사항, 그리고 로케일 업데이트가 포함되어 있었으며, 이는 2023년 말 2.30.1 이후 첫 번째 릴리스였습니다.

또한 이 프로젝트는 2020년에 했던 ‘버전 3을 절대 출시하지 않겠다’는 약속을 철회했습니다. 3.0 버전의 출시 일정은 없으며, 설령 3.0이 출시된다 해도 기능 개발로 복귀하기보다는 여전히 유지보수 릴리스에 그칠 것입니다. 하지만 2020년에 완전히 봉인되었던 문은 이제 그저 닫혀 있을 뿐입니다. 이것이 현재의 경계선이며, 6년 전보다 조금 더 넓어진 상태입니다.

Moment는 OpenJS 재단 산하의 At-Large 프로젝트로 운영되므로, 중립적인 거버넌스 체계를 갖추고 있으며 공개된 보안 정책을 보유하고 있습니다. 그러나 이 두 가지 요소 모두 이전 릴리스 브랜치로 거슬러 올라가는 백포트 작업에 자금을 지원하지 않습니다. 보안 수정 사항은 항상 최신 코드에 적용됩니다.

현실 점검: 2.24.0 버전에 묶여 있는 팀의 경우, 유지보수 모드는 제품 수명 주기(EOL)와 유사한 지원 문제를 야기합니다. 업스트림 보안 작업은 최신 버전의 Moment를 대상으로 진행되므로, 프로젝트 자체는 여전히 활발히 운영되고 있지만 해당 버전에 대한 실질적인 지원 기간은 이미 수년 전에 종료되었습니다.

CVE의 역사는 짧으며, 실제로 사용하는 곳에 바로 적용됩니다.

Moment의 취약점 기록이 적다는 점은 다행스러운 소식입니다. 하지만 문제는 모든 항목이 입력 처리(날짜 파싱, 기간 파싱, 로케일 불러오기)를 담당하는 코드 내에 존재하며, 바로 이 부분들이 애플리케이션이 사용자 데이터를 전달하는 경로라는 점입니다.

CVE 유형 영향을 받는 버전 수정됨 CVSS
31129 RFC 2822 구문 분석 시 발생하는 ReDoS 2.18.0 ~ 2.29.3 2.29.4 7.5 높음
24785 로케일을 통한 경로 탐색 1.0.1 ~ 2.29.1 2.29.2 7.5 높음
18214 구형 파싱에서의 ReDoS 2.19.3 이전 2.19.3 7.5 높음
4055 기간 구문 분석에서의 ReDoS 2.11.2 이전 2.11.2 6.5 보통

CVE-2022-31129은 다음에서 이차(N^2) 규모의 동작을 보입니다. preprocessRFC2822 날짜 문자열에서 레거시 주석을 제거할 때 발생합니다. 충분히 긴 입력값을 제공하면 구문 분석이 중단되는데, 이는 명백한 서비스 거부(DoS) 공격 수단입니다. CVE-2022-24785는 Moment의 로케일을 전환하는 데 사용되는 사용자 제공 로케일 문자열을 통한 경로 트래버설 취약점으로, 2.29.2 버전에서 패치되었습니다. CVE-2017-18214는 이전 릴리스의 구문 분석 정규 표현식에서 발견된 초기 ReDoS 취약점이며, CVE-2016-4055는 duration(), 2.11.2 버전에서 수정되었습니다.

이 애플리케이션에서 심각도를 결정하는 핵심 질문은 매우 구체적입니다. 공격자가 제어하는 입력이 Moment 생성자에 도달할 수 있는지, moment.duration(), 또는 로케일 전환 기능, 그리고 입력 과정에서 이를 검증하는 것은 무엇인가요? 신뢰할 수 없는 내용이 해당 경로에 도달하지 않는다면, 실제 위험 노출 수준은 원점수가 시사하는 것보다 낮습니다.

주의하세요: Moment에 전달되기 전에 날짜나 기간 문자열의 길이를 제한하십시오. CVE-2022-31129에 대한 유지보수 담당자들의 권고 사항에서는 200자 이내로 제한할 것을 권장하고 있으며, 이는 RFC2822 버그를 해소하고 나머지 두 가지 버그에 대한 노출 위험을 크게 줄여줍니다. 같은 권고 사항에 따르면, 이러한 필터는 향후 발생할 대부분의 ReDoS 버그에도 도움이 된다고 합니다. 하지만 로케일 버그에 대해서는 아무런 효과가 없습니다. 로케일 버그의 경우, 오직 수동으로만 moment.locale() 실제로 배포하는 로케일 허용 목록에서 가져온 문자열.

Moment.js에 대한 TuxCare의 평생 라이프사이클 지원 이 문제는 2.0.0, 2.10.6, 2.24.0 버전을 포함하며, 이 세 버전 모두 2.29.x 패치 이전에 해당합니다. 경로 탐색 취약점(CVE-2022-24785)은 이 모든 버전에 영향을 미칩니다. ReDoS 관련 CVE는 버전별로 구분됩니다. RFC2822 ReDoS(CVE-2022-31129)는 2.18.0부터 적용되므로 2.24.0에는 영향을 미치지만, 그보다 이전 두 버전에는 영향을 미치지 않습니다. 구형 파싱 ReDoS(CVE-2017-18214)는 2.24.0이 출시되기 전에 수정되었으므로, 이 취약점은 2.0.0과 2.10.6 버전에만 존재합니다. 지속 시간 기반 ReDoS(CVE-2016-4055)의 영향 범위는 더 좁아져 2.10.6 버전에만 영향을 미칩니다. 2.0.0 버전은 공개된 범위 내에 포함되지만, 그 duration() 문자열을 전혀 파싱하지 않기 때문에, 취약점을 유발하는 정규 표현식은 애초에 존재하지 않습니다.

TuxCare는 자사가 지원하는 버전에 적용되는 이러한 CVE에 대해 이미 모두 패치를 출시했습니다. CVE 트래커를 방문하시면 TuxCare가 지원하는 오픈 소스 소프트웨어 및 해당 의존성 체인에 걸쳐 존재하는 모든 취약점과 사용 가능한 수정 사항을 확인하실 수 있습니다.

Moment.js의 대체 라이브러리를 선택하는 것은 쉬운 일입니다

떠나기로 마음먹었다면, 고려할 사항은 많지 않으며 그중에서 하나를 고르는 건 금방 끝나는 일입니다. 첫 번째 선택지는 절대 그 자리에서 변하지 않는 라이브러리입니다. Luxon과 Day.js는 새로운 불변 객체를 반환하는 반면, date-fns는 일반 Date 값을 반환하고 새로운 값을 반환합니다. 두 번째 방법은 내장 함수를 활용합니다. Intl 서식 지정 및 로케일 처리를 위한 API입니다. 세 번째는 네이티브 Temporal API로, 2026년 3월에 TC39 Stage 4 단계에 도달했으며 이미 Chrome, Edge, Firefox에 탑재되어 있습니다. Safari는 현재 Technology Preview 단계에서만 지원되지만, 이 기능이 모든 브라우저에 정식 적용되면 많은 사용 사례에서 타사 라이브러리 사용이 선택 사항이 될 것입니다.

더 어려운 질문은 현재 여러분의 애플리케이션이 Moment의 어떤 동작에 의존하고 있는지 파악하는 것입니다. 왜냐하면 이를 통해 교체 시 어떤 부분이 오작동하게 될지 결정되기 때문입니다. 객관적으로 더 잘 설계된 라이브러리라 할지라도, 여러분의 코드가 수년 동안 Moment에 제공해 온 것과 똑같은 입력에 대해 서로 다른 출력을 생성할 수 있습니다.

Moment Timezone은 별도의 결정 사항으로 간주하십시오. 이 라이브러리는 자체적인 시간대 데이터 번들과 API 인터페이스를 갖추고 있으며, 이를 기반으로 구축된 시간대 인식 코드가 작업 중 더 어려운 부분입니다. 날짜 형식만 지정하는 코드는 쉽게 이전할 수 있지만, 일광 절약 시간제 변경 시점을 넘나들며 시간대 연산을 수행하는 코드는 그렇지 않습니다.

마이그레이션을 방해하는 날짜 의미론

바로 이 부분에서 Moment 마이그레이션이 실제로 실패합니다. API 구조는 변환하기 쉽지만, 그 이면에 있는 의미론은 그렇지 않습니다.

변경 가능성부터 살펴보겠습니다. Moment 객체는 제자리에서 변경되므로, .add() 그리고 .startOf() 호출한 인스턴스를 변경하십시오. 공유된 Moment 인스턴스를 전달하며 각 호출이 이를 수정할 것이라고 기대하는 코드는, 종종 아무도 눈치채지 못한 채로 그러한 동작에 의존하게 됩니다. Luxon, Day.js, Temporal은 대신 새로운 객체를 반환하며, date-fns 함수들도 새로운 객체를 반환합니다. Date 값들. 해당 호출 패턴을 그대로 적용하면, 변경하려 했던 값이 전혀 변경되지 않았기 때문에 오류가 발생하지 않고 조용히 잘못된 결과를 반환합니다.

그리고 구문 분석도 있습니다. Moment는 설계상 관대한 편입니다. 더 엄격한 라이브러리들이 아예 거부하거나 다르게 해석하는 입력도 받아들이며, 문자열이 ISO 8601이나 RFC 2822 표준을 따르지 않을 경우 기본 구현으로 돌아갑니다. Date 생성자(constructor)는 ‘하루 차이로 발생하는 버그’의 전형적인 원인입니다. 더 엄격한 파서를 적용하면, 예전에는 ‘정상적으로 작동’하던 입력값이 이제는 거부되거나 다른 날짜로 처리될 수 있습니다.

알아두면 좋은 팁: 포맷 토큰도 이식성이 없습니다. Moment의 YYYY-MM-DD 는 yyyy-MM-dd date-fns와 Luxon에서. Day.js는 Moment의 토큰을 유지하며, date-fns는 적어도 YYYY 기본적으로. Luxon은 전혀 예외를 발생시키지 않습니다. 이를 인식하지 못합니다. YYYY 그리고 이를 그대로 출력하고, 그리고 DD 그곳의 현지화된 날짜를 의미하므로, YYYY-MM-DD “YYYY-12-Dec 29, 2026”과 같은 형식으로 출력됩니다. 토큰 문자열에 대한 기계적인 찾기 및 바꾸기 작업은 컴파일러가 감지하지 못하는 잘못된 출력을 아무런 경고 없이 생성하는 것으로 잘 알려진 방법입니다.

시간대 문제는 더 심각합니다. 현지 시간과 UTC의 차이, 일광 절약 시간제 전환, 과거 시간대 데이터 등은 라이브러리마다 미묘하게 다를 수 있으며, 이러한 차이는 특정 날짜에 이르러서야 드러납니다. 로케일 데이터와 형식 토큰도 서로 다르지만, 어느 것도 뚜렷한 오류 메시지를 표시하지 않습니다.

이것이 위험한 이유는 바로 실패 방식 때문입니다. 테스트는 통과하고, 빌드는 문제없이 완료되며, CI에서도 아무런 오류 메시지가 나타나지 않습니다. 그러다 월말 보고서가 하루 늦게 나오는데, 이는 특정 시간대에 속한 사용자들 중에서도 시간대 경계선에 있는 사용자들에게만 해당됩니다.

차트 구성, CSV 내보내기, 정기 이메일 요약 보고서 등에 걸쳐 약 400개의 Moment 호출 지점이 분포된 SaaS 분석 제품을 상상해 보세요. 차트와 내보내기 기능은 지속적으로 사용되므로, 관련 버그는 빠르게 발견됩니다. 반면 정기 요약 보고서는 한 달에 한 번 실행되며, 수신자의 시간대에 맞춰 날짜 범위를 형식화하지만, 아무도 눈치채지 못하는 사이에 일부 고객에게 잘못된 기간의 보고서를 전체 청구 주기 동안 조용히 전송해 버립니다. 이것이 바로 Moment 마이그레이션이 실패했을 때 실제로 나타나는 모습입니다.

행동을 중심으로 수립된 대체 계획

대규모 코드베이스에서도 살아남는 설계는 문자열을 전역적으로 검색하는 방식이 아니라, 동작을 중심으로 구성됩니다. moment. 쉬운 부분이 제대로 작동한다는 것을 확인한 후에야, 위험한 부분을 마지막에 처리합니다.

먼저, 전이적 의존성과 벤더 번들 또는 컴포넌트 라이브러리에 포함된 복사본을 포함하여 모든 Moment 및 Moment Timezone 사용처를 찾아내십시오. 그런 다음 각 호출 위치를 실제 수행하는 작업(구문 분석, 서식 지정, 산술 연산, 현지화, 시간대 연산 등)에 따라 분류하십시오. 이러한 범주들은 마이그레이션 위험이 매우 다르기 때문에, 이를 한데 묶어 처리할 경우 팀은 예상치 못한 문제에 직면하게 됩니다.

코드를 한 줄도 수정하기 전에 실제 날짜와 알려진 경계 사례를 대상으로 회귀 테스트를 추가하세요. 일광 절약 시간제 적용 경계, 윤년, 월말 이월, 그리고 UTC를 사용하지 않는 사용자들 관련 부분이 특히 골칫거리입니다. 다음으로, 날짜 처리를 내부 날짜 모듈을 통해 처리하도록 하여, 코드 곳곳에 흩어져 있는 400곳의 직접 호출 지점 대신 안정적인 인터페이스 뒤에서 기본 라이브러리를 자유롭게 교체할 수 있는 구현 세부 사항으로 만들세요. 바로 그 래퍼가 실제로 효과가 입증된 패턴입니다.

그 후에야 비로소 좁고 위험이 낮은 사용 사례를 교체해야 하며, 이를 통해 더 어려운 사용 사례에 대한 자신감과 도구를 마련할 수 있습니다. 무엇보다도, 두 데이터 모델 사이에 명확한 경계가 없는 상태에서 동일한 비즈니스 워크플로우에서 두 모델을 동시에 실행하는 것은 피해야 합니다. 하나의 흐름에 가변적 로직과 불변적 로직이 혼합되어 있으면 그 자체가 버그의 온상이 되기 때문입니다.

결정 내리기: 설치 공간이 작고, 테스트 커버리지가 탄탄하며, 시간대 관련 로직이 없다면? 지금 바로 마이그레이션하세요. 시간대나 로케일을 많이 사용하나요? 먼저 래핑한 다음, 모듈별로 순차적으로 마이그레이션하세요. 번들이 고정되어 있거나, 벤더 컴포넌트가 Moment를 포함하고 있다면? 패키징 구조가 허용하는 범위 내에서 의존성을 업그레이드하거나 오버라이드하고, 완전한 제거를 당장 실행해야 할 로드맵 항목으로 간주하는 것은 그만두세요.

어떤 상황에서 ‘모멘트’를 일시적으로 유지하는 것이 합리적인 선택인지

때로는 “이번 분기에는 마이그레이션을 진행하지 않겠다”는 것이 솔직한 답변일 수 있으며, 이는 올바른 결정일 수도 있습니다. 하루의 오류만으로도 규정 준수 위반 사유가 되는 규제 대상 또는 금융 관련 날짜 처리 로직, 로케일 동작을 완전히 문서화하지 못한 대규모 국제화 애플리케이션, 릴리스 주기가 긴 임베디드 제품, 또는 서둘러 진행한 마이그레이션을 검증할 만한 테스트 범위가 부족한 애플리케이션 등을 생각해 보십시오. 이러한 모든 경우에서, 시간적 압박 속에서 Moment를 강제로 제거하는 것은 더 위험한 선택입니다.

한 가지 주의할 점이 있습니다. ‘일시적’이라는 표현에는 소유자, 날짜, 그리고 허가증이 필요합니다. 이 세 가지가 없다면, ‘일시적’이라는 말은 다음 감사 때에도 여전히 그 자리에 남아 있다는 뜻에 불과합니다.

바로 이러한 격차를 메우기 위해 공급업체 지원 패치 서비스가 마련된 것입니다. TuxCare의 ELS는 다음을 지원합니다. moment 2.0.0, 2.10.6, 2.24.0 및 moment-timezone 0.4.1, 그 범위 내에서 자바스크립트 라이브러리 적용 범위. 수정 사항은 다음을 통해 제공됩니다. npm SBOM 및 VEX 데이터가 포함되어 있어 출처 추적 기록이 감사 가능합니다. Moment 자체는 런타임 종속성이 전혀 없으므로, 커버리지 문제는 Moment에 집중되며 그 아래에 있는 일련의 패키지들에 대한 것은 아닙니다.

고정된 버전에 대한 보안 패치 작업은 계속 진행되며, 동시에 사용 행동 중심의 마이그레이션 테스트도 적절한 속도로 진행되므로, 관련 없는 정보 공개 일정에 맞춰 날짜 로직을 재작성해야 하는 압박감에서 벗어날 수 있습니다. 정보 공개 일정이 아닌, 여러분만의 일정에 맞춰 마이그레이션을 진행할 수 있습니다.

OpenJS와 지속가능성이 어떤 역할을 하는지

Moment는 OpenJS 재단이 운영하며, 이 재단은 ‘생태계 지속 가능성 프로그램(Ecosystem Sustainability Program)’을 통해 자사 프로젝트의 보관된 버전, 지원 종료된 버전 및 구버전에 상업적 보안 서비스를 제공하며, 해당 수익의 일부를 해당 프로젝트에 환원하고 있습니다. TuxCare는 골드 회원 및 제공업체로 참여하고 있으며, 이 프로그램은 비독점적입니다.

가장 좋은 대안은 여러분이 이미 검증해 본 것입니다.

벤치마크 수치는 월말에 여러분을 구해 주지 못합니다. 최고의 Moment.js 대안은, 비즈니스상 절대 실수할 수 없는 날짜를 기준으로 그 의미 체계가 검증된 것입니다.

요약
Moment.js는 더 이상 사용되지 않는가요? 구버전 현황, CVE 및 지원 옵션
기사 이름
Moment.js는 더 이상 사용되지 않는가요? 구버전 현황, CVE 및 지원 옵션
설명
Moment.js는 유지보수 모드에 있는 레거시 프로젝트입니다. 이것이 보안에 어떤 영향을 미치는지, 실행 시 마이그레이션이 실패하는 이유, 그리고 어떤 대안이 있는지 확인해 보세요.
작성자
게시자 이름
TuxCare
게시자 로고

4,500명 이상의 Linux 및 오픈 소스 전문가와 함께하세요!

한 달에 두 번. 스팸이 없습니다.

목차
필요한 오픈 소스 보안에 대한 답변 얻기

4,500명 이상의 Linux 및 오픈 소스 전문가와 함께하세요!

한 달에 두 번. 스팸이 없습니다.