개발/개발 환경

npm-check-updates와 npm audit으로 Node.js 패키지 취약점 손쉽게 관리하기

꾸럭 2025. 3. 27. 09:31

Node.js로 프로젝트를 만들다 보면 수십 개, 많게는 수백 개의 패키지를 설치하게 된다. 직접 설치한 것도 있지만 대부분은 의존성으로 따라온 것들이다. 문제는 이 패키지들 중 하나라도 취약점이 생기면, 전체 프로젝트가 위험해질 수 있다는 점이다.

 

아직 보고되지 않은 잠재적인 취약점까지 개발자 선에서 모두 찾아내고 조치하는 건 사실상 불가능에 가깝다. 그렇기 때문에 적어도 이미 보고된 취약점에 대해서는 빠르게 대응하는 태도가 필요하다. 이런 취약점은 공개된 만큼 악용될 가능성도 높고, 보안 사고로 이어질 위험도 크다.

 

보고된 취약점에 대응하는 방법은 크게 두 가지다. 하나는 내가 직접 package.json에 선언한 의존성 패키지의 버전을 가능한 최신으로 유지하는 것, 다른 하나는 이런 패키지에 딸려온 하위 의존성들 중 취약점이 있는 버전을 찾아내어, 이를 해결한 버전으로 교체하는 것이다.

 

그렇다면, 이런 복잡한 일들을 개발자가 매번 손으로 일일이 확인하고 처리해야 할까?

다행히, 꼭 그럴 필요는 없다.

ncu (npm-check-updates): 직접 선언한 패키지 버전 관리

먼저 소개할 도구는 ncu, 정확한 이름은 npm-check-updates다.

이 도구는 내가 직접 package.json에 명시한 의존성들의 최신 버전을 확인하고, 한 줄 명령어로 업데이트해주는 역할을 한다. 기본적인 npm install만으로는 메이저 버전 업데이트가 자동으로 되지 않기 때문에, ncu를 활용하면 놓치고 있던 중요한 업데이트도 쉽게 반영할 수 있다.

 

설치는 전역으로 하는 게 일반적이다.

npm install -g npm-check-updates

 

설치가 끝났다면, 프로젝트 루트 디렉토리에서 아래 명령어를 실행하면 된다.

ncu

 

이 명령어는 현재 사용 중인 패키지들과 업데이트 가능한 최신 버전의 목록을 보여준다. 실제로 버전을 올리고 싶다면 다음과 같이 하면 된다.

ncu -u

 

이후 npm install만 해주면 최신 버전이 적용된다.

 

최신 버전 업데이트, 항상 좋은 걸까?

ncu -u는 기본적으로 모든 패키지를 가장 최신 버전으로 올리려는 시도를 한다. 그런데 프로젝트가 점점 커질수록, 모든 패키지를 항상 최신 상태로 유지하는 건 어렵고 위험한 일이 되기도 한다.

 

메이저 버전이 올라가면서 API가 크게 바뀌는 경우도 있고, 최신 버전에 오히려 치명적인 버그가 있어 업데이트를 미뤄야 할 때도 있다. 이럴 땐 다음과 같이 범위를 좁힌 업데이트가 유용하다.

ncu -t minor
ncu -t patch

 

-t minor는 마이너와 패치만, -t patch는 패치만 업데이트한다. 안정성을 유지하면서도 적절한 수준의 업데이트를 할 수 있는 옵션이다.

 

특정 패키지를 업데이트에서 제외하고 싶다면?

특정 패키지는 버전을 고정해두고 싶은 경우도 있다. ncu-x 옵션으로 예외를 둘 수 있다.

ncu -x react,react-dom

 

이 외에도 .ncurc.json, .ncurc.js 등의 설정 파일을 통해 반복적으로 사용하는 옵션들을 미리 정의해둘 수도 있다. 예를 들어 아래처럼 구성할 수 있다.

{
  "target": "minor",
  "reject": ["react", "react-dom"]
}

 

ncu의 다양한 옵션과 설정 파일 구성 방법은 공식 문서를 참고하면 더 자세히 확인할 수 있다.

 

npm audit: 하위 의존성 취약점 점검 도구

직접 명시한 패키지는 ncu로 관리할 수 있지만, 그에 딸려오는 하위 의존성들에 대해서는 npm audit이 필요하다. npm audit은 설치된 모든 패키지를 대상으로, 이미 알려진 취약점이 있는 버전이 있는지 점검해주는 도구다.

 

아래 명령어로 간단히 실행할 수 있다.

npm audit

 

실행하면 취약점의 개수, 심각도, 어떤 패키지에서 발생했는지, 어떤 경로로 설치됐는지까지 상세히 알려준다.

 

자동으로 고칠 수 있다면?

취약점 중 일부는 자동으로 해결할 수 있다. 그럴 땐 다음 명령어를 사용한다.

npm audit fix

 

가능한 범위 내에서 package-lock.json을 수정하고 안전하게 취약점을 해결해준다.

좀 더 강제적인 해결을 원한다면 다음과 같이 사용할 수도 있다.

npm audit fix --force

 

하지만 --force는 메이저 버전 업데이트까지 강제로 수행하기 때문에, 예기치 않은 문제를 유발할 수 있다. 신중하게 사용해야 한다.

 

업데이트 이후, 어떤 점을 주의해야 할까?

ncu와 npm audit 모두 결국은 의존성의 버전을 변경하는 도구다. 버전을 바꾼다는 건 코드의 동작이 달라질 수 있다는 뜻이고, 이는 프로젝트 전반에 영향을 줄 수 있다.

 

이런 변경은 개발 단계에서의 에디터 오류, 빌드 시점의 컴파일 실패, 실행 후의 런타임 예외 등으로 나타날 수 있다. 특히 버전 변화가 클수록 이러한 문제가 생길 가능성도 커진다.

 

의존성 업데이트 이후에는 반드시 테스트를 돌리고, 앱을 직접 실행해보면서 주요 기능이 정상적으로 동작하는지 확인해야 한다. 변경된 패키지가 어떤 기능과 연결돼 있는지를 잘 파악하고 있다면 훨씬 수월하게 검증할 수 있다.

 

실무 팁: Cursor로 변경 영향도 분석해보기

이런 점검 과정을 조금 더 수월하게 하고 싶다면, Cursor 같은 AI 기반 코드 편집기를 활용해보는 것도 방법이다. Cursor는 프로젝트 전반을 백그라운드로 불러와 문맥을 이해하고 명령을 수행한다.

 

직접적으로 영향도를 분석하는 기능이 내장돼 있는 건 아니지만, 프롬프트를 잘 작성하면 매우 효과적인 도구가 된다. 예를 들어 아래와 같은 식으로 요청할 수 있다.

“지금 ncu -u를 실행해서 package.json이 바뀌었어. 이 변경이 프로젝트에 어떤 영향을 줄 수 있을지 전체적으로 확인해줘.”

 

이런 방식으로 변경된 버전이 사용된 코드 위치를 추적하고, 영향 가능성이 있는 부분을 빠르게 짚어낼 수 있다. 다만, 아무리 AI의 도움을 받더라도 의존도가 높거나, 말썽이 잦았던 패키지에 대해서는 반드시 직접 런타임에서 확인해보는 것이 안전하다.

 

정기적인 관리가 최고의 보안, 그리고 최고의 유지보수

의존성 관리는 한 번 하고 끝나는 일이 아니다. 시간이 지날수록 패키지는 계속 업데이트되고, 새로운 취약점도 발견된다. 결국 중요한 건 얼마나 자주, 꾸준히 점검하고 관리하느냐다.

 

가장 현실적인 방법은 루틴을 만드는 것이다. 예를 들어 매주 월요일 오전이나 배포가 끝난 직후, ncunpm audit을 정기적으로 실행해보는 시간을 정해두는 식이다. 팀 단위로는 CI 파이프라인에 npm audit을 자동화해서 돌리는 것도 효과적이다. pull request마다 자동 점검을 하도록 설정하면 사전에 문제를 걸러낼 수 있다.

 

여러 회사를 거치면서 느낀 건, 지금처럼 보안 도메인을 다루는 회사를 제외하면 대부분의 팀은 패키지 관리를 체계적으로 하지 않았다는 점이다. 의존성 업데이트는 대체로 지금 필요한 기능이 최신 버전에 있을 때만 하는 경우가 많았고, 주기적인 점검은 문화 자체에 없었다.

 

그 결과, 프로젝트 전체가 구버전에 강하게 결합돼 버리는 일이 많았다. 한두 개 패키지를 바꾸는 데도 관련된 모든 코드가 줄줄이 영향을 받아 안정성을 해치는 경우가 많았다. 이런 상황을 겪고 나서야 “처음부터 조금씩 관리했으면 더 좋았을 텐데”라는 생각이 들었다.

 

그래서 지금은 ncunpm audit을 기반으로 한 정기적인 의존성 관리 루틴이 단지 보안을 위한 게 아니라, 프로젝트를 오래도록 안정적으로 유지하는 가장 현실적인 방법이라고 생각하게 됐다.

 

자주, 작게, 꾸준히 관리하는 것이 결국엔 더 빠르고 더 안전한 길이다.

728x90
반응형

'개발 > 개발 환경' 카테고리의 다른 글

Mac에서 Open JDK 설치  (0) 2021.06.07
이미 push된 file .gitignore 적용하기  (0) 2021.04.23
AWS LightSail MySQL 세팅  (0) 2021.04.22