소프트웨어 취약점 관리: npm audit 그리고 SBOM
이 글에서는 다음과 같은 내용을 다룹니다.
npm audit
간략 소개npm audit
데이터 원천과 활용npm audit
한계와--production
옵션에 대해- 더 나아가기: BOM & SBOM
최근에 colors(node.js 콘솔 텍스트에 색상을 입히는 패키지)와 faker(테스트 또는 시연용 더미 데이터 생성 패키지) NPM 패키지 메인테이너 Marak Squires가 ‘공짜로 포춘 500 대기업의 서포터가 되고 싶지 않다(he wrote that he no longer intended to support Fortune 500 and other companies with his free work.)’는 이유로 두 패키지에 악성 코드를 넣고 새 버전을 배포한 일이 있었습니다.
더미 데이터를 생성하는 상당수 라이브러리가 faker를 기반으로 만들었기 때문에 금번 배포로 인해 피해를 입은 사람들의 숫자가 상당하다고 합니다. 프로젝트에서 이러한 라이브러리를 사용중이라면, 이상이 생겼는지 어떻게 알 수 있을까요?
그의 패키지로 인해 소프트웨어에 결함이 생겼으므로, 해당 패키지는 소프트웨어 분석을 한다면 취약점으로 분류될 것입니다. 분석을 하는 한가지 방법은 NPM에서 제공하는 npm audit
명령어를 사용하는 것입니다.
`npm audit` 명령어
npm audit
은 GitHub 경보(Advisory) DB를 바탕으로 프로젝트 의존 패키지의 취약점을 분석해 결과를 아래와 같이 터미널에 출력합니다.
위 테이블을 보면, numbat-emitter라는 패키지의 의존성인 hoek 패키지가 prototype pollution(이래서 Object.freeze()
를 사용해야 하는군요!) 사유로 Moderate 등급의 심각성이 보고됐음을 알 수 있습니다. ‘Patched in’ 열의 버전 정보를 보고 버전을 수정하면 됩니다. 4.2.0 보다 높고 5.0.0 보다 낮은 버전, 또는 5.0.3 이상 버전으로 고치라는 뜻입니다.
생성한 보고서를 html 파일로 이쁘게 뽑아보고 싶다면 npm-audit-html 패키지를 설치한 뒤 npm audit 명령어와 연결해 같이 사용하면 됩니다.
그렇지만 보고서 결과를 곧이 곧대로 보고 수정한다 해서 쉽게 뚝딱 다 고쳐지는 것이 것이 아닙니다. 한계가 있는데 뒤에서 따로 설명합니다.
npm audit 데이터 원천
위 문서에 따르면 npm audit 명령어가 정보를 가져오는 곳이 GitHub Advisory DB인데, 이 DB는 또 다음과 같은 곳에서 데이터를 모아 온다고 합니다.
- 미국 국립 취약점 DB(The National Vulnerability Database)
- 머신 러닝과 사람 리뷰를 결합한 GitHub 공개 커밋 취약점 분석
- GitHub에 보고된 보안 경보
- npm 보안 경보 DB
Github 의존성봇
저장소에 올라오는 귀여운 의존성봇(Dependabot) 메시지의 원천이 바로 위의 곳들 입니다. 각종 원천에서 모아온 경보 데이터는 Github에서 리뷰를 완료한 경보와 그렇지 않은 경보로 나뉩니다.
의존성봇은 리뷰가 완료된 경보, 즉 GitHub 의존성 그래프에 매핑된 패키지의 보안 취약점만 저장소에 알립니다. GitHub에서 유효성 검증을 하지 않은 경보에 대해서는 의존성봇이 저장소에 따로 알려주지 않습니다.
외부 서비스
Github을 사용하지 않거나, 별도의 외부 코드 분석 툴을 사용하고 있다면 그 툴에서 제공하는 분석 서비스를 사용해도 됩니다. 사례로 Synk와 JFrog, 그리고 Gitlab을 설명하겠습니다.
Synk
synk는 클라우드 컴퓨팅에 특화된 사이버보안 회사입니다. 회사의 제품 중 하나로 취약점 데이터베이스(Vulnerability Database)가 있습니다.
만약 synk를 저장소의 CI/CD 설정을 통해 연동해 둔다면 의존성 그래프 분석을 통해 취약점 보고서를 제공합니다. Synk의 DB 사이트에 들어가서 개별 패키지 검색을 통해 해당 패키지에 대한 취약점 해결 방법 검색도 가능합니다.
JFrog
또다른 외부 서비스 예시로 JFrog가 있습니다. CI/CD에 따라 소프트웨어 개발을 하는 경우 소스 코드는 정기적으로 바이너리 아티팩트(artifact)로 빌드됩니다. JFrog는 이러한 아티팩트를 한 곳에 모아두는 Artifactory 저장소 서비스를 제공합니다. 개발자는 다양한 패키지 매니저를 통해 JFrog Artifactory와 상호작용 하며 소프트웨어 개발을 진행합니다.
예를 들어 npm 패키지 매니저를 사용해 빌드 산출물을 JFrog npm registry에 올릴 수 있습니다. Xray(JFrog에 취약점 데이터를 제공) 사용 라이선스를 취득하면 버전 배포 할 때마다 npm audit 명령어를 통해 패키지 취약점 확인이 가능해집니다.
Gitlab 의존성 스캐닝
Gitlab을 사용하는 경우, 의존성 스캐닝 기능을 사용해 취약점 검사가 가능합니다. Auto DevOps 기능을 사용하면 자동으로 의존성 스캐닝 기능까지 설정을 해준다고 합니다. 프로젝트 언어에 따라 Gitlab에서 알아서 CI/CD 파이프라인을 만들어주는 기능이라고 하네요. 2018년에 나온 기능인데 저는 이제서야 알았네요 😅
한계
colors는 알려주고 faker.js는 안 알려줌
그렇지만 직접적으로 악성 코드가 들어가서 synk와 GitHub의 취약점 알림 경보가 colors에는 존재하는 반면, faker는 단지 저장소 코드가 아무런 일을 하지 않는 평범한 텍스트로 대체됐기 때문에 특별히 생성된 경보가 없습니다.
만약 사용중인 라이브러리가 이런 상태가 됐다면 외부 창구를 통해 소식을 듣기 전이나, 개발 중에 현상과 직접 마주하기 전에는 알 방법이 딱히 없는 것 같습니다.
개발 의존성인 경우
Dan Abramov가 ‘npm audit: Broken by Design’이라는 제목의 글에서 언급했듯이, 외부 침입 공격이 발생할 염려가 전혀(거의) 없는 개인 로컬 환경에서 받아 보는 npm audit 보고서는 걱정할 필요가 별로 없습니다. 공격자가 힘들여서 뚫고 로컬에 들어왔는데 겨우 한다는 일이 npm 패키지 취약점 공격은 아니지 않을까요?
a라는 패키지를 프로젝트에서도 사용하고 b라는 패키지의 의존성으로도 a가 걸려있는 경우를 가정해봅시다. 그런데 두개 버전이 다른 경우, 문제가 발생합니다. 의존성 보고서에 따르면 a 패키지 버전을 강제로 업데이트 하라는데, 이러면 프로젝트에서 b 패키지 사용이 불가능해질 수도 있습니다. b 패키지가 사용하는 a 버전의 싱크가 맞지 않는 경우에 말이죠. 특히 a와 b 패키지가 모두 개발 의존성이라면, 애초에 그냥 사용해도 되지 않았을까요?
production 옵션 사용하기
그러므로 npm audit 명령어를 실행할 때에는 production 옵션을 넣어서 (npm audit --production
)개발 의존성이 아닌 실제 빌드에 들어가는 의존성에 관해서만 audit 명령어가 실행되도록 제한을 걸어줍니다. 개발 의존성과 관련된 취약점 보고서의 양이 길어질수록 쏟은 시간에 비해 얻은 게 별로 없는 상황이 벌어질 수도 있습니다.
더 나아가기
SBOM (Software Bill of Materials)
NPM에서 벗어나 더 넓게 오픈소스 사용을 바라보면, 취약성 검사에 SBOM을 활용합니다. 부끄럽지만 저는 올해 처음 오픈 소스 보안 관련 교육을 듣다가 알게 된 단어입니다. 교육을 듣다보니, NPM의 package.json
파일이 SBOM의 일종이 아닌가 싶은 느낌이 들어 찾아보게 됐습니다.
BOM (Bill of Materials)
SBOM에 대해 이야기하기 전에 BOM 부터 살펴보겠습니다. ‘Bill of Materials’는 ‘재료표', ‘부품 구성표', ‘제품 구성 사양' 등의 뜻을 가집니다. 아래 그림과 같은 표는 BOM의 예시입니다.
부품, 부분, 재료 등을 수량과 연결 문서와 함께 모아둔 제품 전체 정보 집합을 BOM이라 합니다. 최종 제품 생산에 필요한 중요 컴포넌트(부분, 재료, 조립)가 포함된 제품 구조 또한 BOM에 해당합니다.
출처: https://www.openbom.com/blog/what-is-bom-bill-of-materials
제조업계에서 공급 체인을 관리할 때 BOM은 널리 쓰인다고 합니다. 예를 들어, 자동차를 만들때 제조사는 각 차량에 들어가는 부품 목록을 전부 관리해야 합니다. BOM의 일부는 원 제조사가 관리하고 일부는 서드파티 공급사에서 관리합니다. 그래야 결함 부품 발견시, 부품 교체가 필요한 차량 정보를 신속하게 알 수 있습니다.
이와 비슷하게, 소프트웨어 업계에서는 SBOM을 사용해 그 안에 들어가는 온갖 부품의 상태를 파악 가능합니다.
오픈 소스가 소프트웨어 개발에 활발히 사용되는 만큼, 하자 없이 제대로 사용되고 있는지 검사가 필요한데 그때 Blackduck과 같은 소프트웨어 구성 분석(SCA, Software Composition Analysis) 툴을 사용합니다. 구성 분석 툴을 통해 SBOM을 생성하고, 소프트웨어의 내부 구성 성분에 대해 알고 싶은 사람 혹은 기계는 언제든지 SBOM을 활용할 수 있습니다.
npm audit
으로 충분한 줄 알았는데 너무 안이한 생각이었나 보네요. 이런 툴을 사용하는 이유가 궁금해서 찾아봤습니다.
‘The license and security risks of using Node.js’라는 글에 따르면, 고용된 직원이 직접 코드 감사(audit)를 수행해서, 미처 오픈 소스 재사용성을 고려하지 못해 나중에 문제가 발생할 가능성이 있는 라이센스를 보유한 의존성을 찾을 수 있다고 합니다. 패키지 간 라이센스 충돌 여부 감지가 자동 스캐닝 도구보다 좀 더 세심하게 이루어지는 것입니다. 회사의 정책과 사용중인 오픈 소스 라이센스 관리를 효율적으로 도와주는 것도 다른 장점이 될 수 있겠네요.
정리
npm audit
부터 시작해서, npm 취약성 데이터의 원천, 취약성 관리 관련 외부 서비스를 알아봤습니다. 문득 별 생각 없이 사용하던 NPM 패키지가 많은 데이터와 사람들의 노고가 얽혀있음을 다시 한번 확인 할 수 있는 기회였습니다.
그리고 어쩌다 보니, 좀 더 넓은 범위로 거슬러 올라가 SBOM 까지 살펴봤네요. 가끔씩 자신이 사용하고 있는 툴이나 언어에서 벗어나 넓은 범위에서 소프트웨어 개발을 바라보면 새로운 것을 배우게 되는 것 같습니다. (살짝 글의 흐름이 의식의 흐름인 것 같지만…)
글에서 인용한 React 생태계의 아버지 댄 아브라모브가 쓴 글인 npm audit: Broken by Design도 추가로 읽어보면 좋은 생각거리가 될 것 같습니다.
오픈소스 라이선스 관리에 대해 더 알아보고 싶다면, 탈잉의 ‘
개발자가 자주 질문하는 오픈소스 라이선스’ 강의를 추천드립니다.
읽어주셔서 감사합니다.
🌟 보너스 1
문제가 됐던 NPM 패키지 관리자 Marak은 faker 리드미 문서에 “애런 슈워츠에게 정말 무슨 일이 있었던 것일까?(What really happened with Aaron Swartz?)”이라는 문장만 남겼습니다.
애런 슈워츠가 누구냐면, 26살의 젊은 나이에 자살로 생을 마감한 미국의 컴퓨터 프로그래머이자 인터넷 활동가입니다. 그에 관해서는 아래와 같은 다큐멘터리도 있습니다.
영화를 본 관객은 이 영화가 애런을 너무 영웅적으로 묘사했다고 비판할 지도 모른다. 그가 “유료 컨텐츠”를 몰래 빼낸 것과 이후 “13건의 범법 행위”로 조사를 받은 “해커”인 건 사실이지 않느냐며 의심의 눈초리를 보낼 수도 있는 것이다. 하지만 감독은 그런 의견들을 하나하나 반박하는 대신 애런이 짧은 생애 동안 이 사회에 제기한 문제들을 꼼꼼히 되새기는데 더 힘을 쏟는다. 우리가 너무 자연스럽게 받아들여왔기 때문에 문제라고도 의식하지 않았던 것들 말이다.
🌟 보너스 2
구글링 하다보니 사용하고 있는 운영체제에 대한 SBOM 생성법까지 나오네요.
This is a good habit to get into. Just remember, when you update applications or the OS, you’ll want to re-run the command, or re-use the GUI, to re-generate a new SBOM, so you’re always up to date. Compare the installed software to your CVE list of choice, and you are better capable of staying on top of the vulnerability game. — Create a Software Bill of Materials for Your Operating System by Jack Wallen
오, 몰랐는데 사실 운영체제 SBOM 만들어 놓는 것이 좋은 습관이라고 합니다. 사용 중인 애플리케이션 버전 정보를 계속 최신으로 갱신하면 취약성 게임의 승자가 될 수 있다고 하니 관심 있는 분들은 많은 참여 부탁드립니다 👏