ClickCease "모든 것"과 Node.js 주방 싱크대까지

콘텐츠 표

인기 뉴스레터 구독하기

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

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

"모든 것"과 Node.js 주방 싱크대까지

조아오 코레이아

2024년 1월 11일 기술 에반젤리스트

  • *공급망은 코드부터 배포까지 모든 수준에서 취약합니다.
  • 개발자가 악성 패키지를 업로드한 후 *Node.js 리포지토리가 사실상 잠겼습니다.

의도한 결과와 의도하지 않은 결과를 구분하기 어려운 경우가 많습니다. 최근 연말연시 '장난'으로 인해 Node.js 개발자들의 삶이 복잡해지면서 '선한 행동은 벌을 받지 않는다'는 익숙한 격언이 다시 한 번 강조되었습니다. 

스토리텔링이 포함되어 있으므로 팝콘과 함께 관람하는 것을 추천합니다.

2016년의 먼 옛날에...

 

...한 Node.js 개발자가 단 11줄의 코드인 "leftpad"라는 이름의 패키지를 만들었습니다. 문자열에 패딩을 추가하는 것은 개발자들이 흔히 하는 작업으로, 일반적으로 같은 것을 반복하지 않는 것을 선호합니다(반복하지 않는 프로그래밍 원칙, DRY). 

당연히 많은 사람들이 '좌측 패드'를 프로젝트에 가져오는 방법을 선택했습니다. 하지만 이러한 의존은 버그, 보안 취약점, 개발자의 변덕 등 '왼쪽 패드'의 모든 문제에 노출될 수 있는 취약점을 낳았습니다. 극적인 반전으로 '왼쪽 패드'의 개발자는 자신의 작품을 삭제할 수 있는 권리를 언급하며 이를 실행에 옮겼습니다. 이 조치로 인해 상당수의 주요 웹사이트가 다운되어 이러한 종속성의 취약성이 부각되었습니다. 공평하게 말하자면, 저자는 그렇게 해야 하는 몇 가지 이유를 제시했으며, 기업의 오픈 소스 코드 상업화에 동의하는지 여부에 따라 이에 대한 견해가 달라질 수 있습니다(자세한 내용은 여기에서를 참조하세요)*.

결국 "왼쪽 패드" 제거로 인해 수많은 타사 패키지와 웹사이트에 심각한 장애가 발생했습니다. 재발을 방지하기 위해 npm 레지스트리는 패키지가 다른 패키지의 종속 요소인 경우 게시를 취소할 수 없도록 하는 정책을 구현했습니다. 이 규칙은 한동안 효과적인 것으로 보였습니다.

 

다 좋은데 최근에 무슨 일이 있었나요?

 

좋은 것만 있을 수는 없으니 사람들은 레지스트리에 도입된 변경 사항을 악용할 수 있는 방법을 찾게 되었습니다. 다른 사람이 의존하는 패키지를 내가 제거할 수 없다면, 내 코드가 다른 사람의 패키지에 의존하는 경우 다른 사람도 내 코드를 제거할 수 없다는 논리를 역으로 적용했습니다... 그리고 당연히 성공했습니다.

그래서 나중에 개발자가 "테스트" 및 "장난"이라고 설명한 대로 "everything"이라는 패키지가 레지스트리에 추가되었습니다. 이 패키지는 종속성으로 "everything chunk 1", "everything chunk 2" 등으로 불리는 다른 패키지 그룹을 포함하는 것 외에는 아무것도 하지 않았습니다. 여기에는 다음이 차례로 포함됩니다. 모든 단일 패키지 를 포함하게 됩니다. 이렇게 하면 패키지에 대한 종속성이 항상 존재하기 때문에 누구도 어떤 패키지를 게시 취소할 수 없었습니다.

하지만 더 나아질 수도 있습니다. 남은 팝콘의 양에 따라 더 나빠질 수도 있습니다.

npm 패키지의 종속성 선언을 통해 개발자는 특정 버전에 "의존"할 수 있습니다. 일반적으로 해당 패키지가 주장하는 작업을 올바르게 수행하는 테스트된 버전이며, 해당 패키지를 포함한 개발자는 해당 동작이 패키지 또는 애플리케이션에 필요한 동작인지 확인하기 위해 광범위한 테스트를 실행했습니다. 

하지만 하나의 버전을 지정하는 데만 국한되지 않습니다. 버전 값으로 "*"를 설정하면 해당 패키지의 *모든* 버전을 종속 요소로 사용할 수 있음을 npm에 효과적으로 알릴 수 있습니다. 

선언에 "*"를 사용했기 때문에 "모든 것"에는 모든 단일 종속성 및 해당 종속성의 모든 단일 버전이 포함됩니다.

따라서 다른 개발자는 버그가 있는 경우와 같이 자신의 패키지를 제거할 수 없을 뿐만 아니라 이전 버전도 제거할 수 없었습니다. 

"모든 것"이 단단히 잠겼습니다.

 

문제가 해결되었나요?

 

예, 다행히도. "everything"의 개발자가 npm 지원팀과 협력하여 문제를 해결하기 위해 "everything 청크" 리포지토리를 비공개로 표시하여 종속성 체인을 끊었습니다(개발자가 사과하는 스크린샷을 포함하여 이에 대한 자세한 내용은 여기).

이 사건은 사이버 보안 및 IT 커뮤니티 전체에 큰 충격을 주었습니다. 한 명의 개발자가 장난(또는 '테스트')으로 이러한 혼란을 일으킨 것이 아니라 심각한 위협 행위자라면 어땠을까요? 코드에 로그4j 수준의 보안 취약점이 있는 다른 패키지의 제거를 금지하는 데 사용된 '모든 것' 스타일의 패키지가 빙산의 일각에 불과하다면 어떻게 될까요?

npm 생태계, 그리고 실제로 이와 유사한 패키지 의존성 중심 환경은 이러한 취약점을 해결하는 데 여전히 상당한 어려움을 겪고 있습니다. 결함을 악용하는 사람들의 창의성을 고려할 때 완벽한 해결책은 없을 수도 있습니다. 

어쩌면 현재 진행 중인 이 전쟁에서 인공지능이 절실히 필요한 도움을 제공할 수도 있습니다.

 

* 사소해 보이지만 영향력 있는 패키지의 더 많은 예를 보려면 다음을 고려하세요. "하나의 라이너 rpm 패키지 "is-windows"에 250만 개의 종속 항목이 있는데, 도대체 왜?!" 스레드를 보세요. 한 명의 개발자가 1400개가 넘는 패키지를 만들었는데, 그 중 대부분은 단순한 한 줄짜리 패키지로, 최소한의 코드가 얼마나 놀라운 영향력을 발휘하는지 보여줍니다.

 

요약
"모든 것"과 Node.js 주방 싱크대까지
기사 이름
"모든 것"과 Node.js 주방 싱크대까지
설명
의도한 결과와 의도하지 않은 결과를 구분하기 어려운 경우가 많습니다. 최근 '장난'으로 인해 Node.js 개발자의 삶이 복잡해졌습니다.
작성자
게시자 이름
TuxCare
게시자 로고

Kernel 재부팅, 시스템 다운타임 또는 예정된 유지 보수 기간 없이 취약성 패치를 자동화하고 싶으신가요?

TuxCare로 라이브 패치에 대해 알아보기

TuxCare 게스트 작가 되기

시작하기

메일

가입

4,500

Linux & 오픈 소스
전문가!


뉴스레터 구독하기