Node EOL부터 Node LTS까지, 그리고 그 사이의 모든 버전

에피소드 개요
HeroDevs와 Node.js 기술 운영 위원회(Technical Steering Committee) 위원인 Matteo Collina, Marco Ippolito와 함께 의사 결정 과정과 주요 이니셔티브가 논의 단계에서 출시 단계로 이어지는 과정을 자세히 살펴보세요. 취약점 보고 접수 및 분류부터 조정된 공개에 이르는 Node.js 취약점 라이프사이클을 파악하고, 빈번해지는 CVE가 미치는 영향이 점차 커지고 있는 현상을 분석해 보시기 바랍니다.
트랜스크립트

마르코, 마테오, 두 분을 모시게 되어 정말 기쁩니다.

안녕하세요. 정말 좋네요.

자, 여러분이 자기소개를 하시기 전에, 먼저 제 소개를 간단히 할게요. 저는 여러분과 Node.js라는 공통점이 있네요. 우리 셋 모두 Node.js를 사용하는 아일랜드 기업에서 일하고 있는 것 같아요. 참 흥미로운 사실이죠.

자, 우선 제 이름은 하비에르 페레즈입니다. 저는 HeroDevs에서 기술 제품 관리 리더로 일하고 있습니다. 저는 자바스크립트 생태계 내의 25개 이상의 기술과 자바스크립트 생태계 외부의 몇 가지 기술, 그리고 물론 Node.js까지 담당하고 있습니다.

제가 마테오, 마르코와 인연이 생긴 계기를 말씀드리자면—음, 지금 생각하면 꽤 오래전인 것 같네요, 대략 12년 전쯤이었죠—저는 아일랜드 워터퍼드에 있는 ‘피드헨리(FeedHenry)’라는 회사에서 일했었는데, 2012년 당시 Node.js가 0.7이나 0.10 버전이었던 시절부터 이미 사용하고 있었습니다. 0.10 버전, 그리고 0.12 버전까지 기억나네요. 그 모든 과정을 겪었죠. 포크가 발생했다가 다시 합쳐지는 과정 같은 역사에 대해서는 굳이 언급할 필요는 없을 것 같습니다. 이미 잘 기록되어 있으니까요.

하지만 그때가 바로 제가 Node.js와 아주 밀접하게 작업했던 시기였습니다. 우리는 RSS 기술과 클라우드 서비스에 연결되는 모바일 앱을 개발하고 있었는데, 이는 고강도 I/O 작업이었습니다. 당시에는 매우 새로운 기술이었지만, 우리는 그것이 우리가 반드시 사용해야 할 기술이라는 것을 알고 있었습니다. 그리고 저는 우리가 틀렸다고 생각하지 않습니다. 우리 CTO와 엔지니어링 팀도 틀리지 않았습니다.

제가 드리고 싶은 말씀은, 여러분과 함께 이곳에 있을 수 있어 정말 기쁘고 설레며, 여러분이 Node 활용하고 계신다는 점이 정말 반갑다는 것입니다. 그동안 많은 일이 있었습니다. 6개월마다 상황이 바뀌곤 하죠, 그렇죠? 때로는 아주 크게 변하기도 하고요. 그래서 이 이야기를 나누는 게 정말 흥미롭습니다. 그럼, 마테오 님부터 시작해 볼까요? 간단히 자기소개를 해 주시겠어요? Node, OpenJS, TSC와 관련된 여러분의 이야기를 들려주세요.

물론이죠. 네, 물론이죠, 물론이죠.

음, 제가 Node 쓰기 시작한 건 2010년쯤이었던 것 같아요. 2011년에는 박사 과정에 들어갔죠. 그 전에는 루비와 자바로 작업했는데, 자바만큼 빠르면서도 루비처럼 개발하기 쉬운 언어를 찾고 있었어요. 루비는 개발할 때는 정말 빠르지만, 실행 속도는 매우 느렸거든요. 적어도 그 당시에는 그랬죠. 지금도 여전히 그런 것 같아요.

그러다 이 영상을 보게 됐는데… ‘바로 이거다’ 싶더라고요. 하지만 솔직히 말해서, 그때가 결정적인 순간은 아니었어요. 그 결정적인 순간은 제가 NPM을 이해하게 된 때였고, NPM이 출시된 때였는데, 바로 그 순간은 아니었어요. 좀 더 시간이 지난 후였죠. 그리고 제가 깨달은 건 — HeroDevs에서 여러분과 이 이야기를 나누던 때로 돌아가자면 — NPM이 대규모로 소프트웨어를 재사용하는 문제를 근본적으로 해결해 줄 것이라는 점이었어요. 그건 그전까지 자바 세계는 물론 루비 세계에서도 큰 문제였죠. NPM 이전에는 아무도 그 해결책을 찾지 못했습니다. 이것이 바로 NPM의 핵심 발명품이며, 그 결과 세계 최대의 레지스트리가 탄생했습니다. 이곳은 훌륭한 것들로 가득 차 있지만, 동시에 가장 큰 표적이 되는 악성 코드들로도 가득 차 있습니다. 따라서 이곳은 가장 매력적인 표적이 되는 셈이죠.

저는 국가 기관이 제 컴퓨터에 접근하기 위해 공격한 대상 중 한 명이었는데, 그 점에서는 운이 없었던 셈이죠. 하지만 그 경험은 정말 유익했습니다. 그래서 Node 일찍부터 Node 사용하기 시작했고, left-pad 취약점이 발생하기 몇 달 전에 이를 예측하기도 했으며, 오랫동안 이 분야에서 최전선에서 활동해 왔습니다.

사실 우리 사이에는 작은 인연이 하나 있습니다. 2013년과 2014년에 저는 NearForm이라는 작은 회사에서 일했는데, 그 사무실은 FeedHenry 바로 옆—말 그대로 바로 옆—에 있었거든요. 그래서 우리 사이에는 이런 작은 인연이 있는 셈이죠. 지난 몇 년 동안 FeedHenry에서 NearForm으로, 또는 그 반대로 몇몇 사람들이 이직하기도 했습니다. 꽤 흥미로운 여정이었습니다. 아마도 우리는 같은 시기에 아일랜드에 있었고, 바로 옆 사무실에서 일하고 있었을 겁니다. 정말 즐거운 시절이었죠.

그 모든 소동이 있은 후부터 Node.js에 기여하기 시작했습니다. IOJS 분열은 큰 사건이었고, 그 후 재단이 설립되었죠. Node 고치고 싶은 부분이 Node 그럴 수 없었는데, 재단이 설립된 후부터 그 일을 시작하게 되었습니다. 처음에는 Node 조금씩 기여하다가, 몇 년이 지나자 CTC(Community Technical Committee)의 일원이 되었고, 그 위원회는 나중에 TSC(Technical Steering Committee)로 통합되었습니다. 그러다 어쩌다 보니 — 잘 모르겠지만 — 운이 좋지 않게도 Node.js TSC 의장으로 선출되었습니다.

TSC에 대해서는 나중에 더 이야기해 봅시다. 마테오, 당신이 해온 일들만 이야기해도 몇 시간은 족히 걸릴 것 같네요. 피노와 Fastify 대해서는 어때요?

제가 파악하기로는, 지난 1년 동안 제가 이 생태계에서 관리하는 모든 모듈의 다운로드 횟수가 420억 회에 달한 것으로 나타났습니다.

미쳤다. 믿을 수가 없어.

그리고 Fastify 이름에서 알 수 있듯이 가장 빠른 프레임워크죠, 그렇죠?

그래. 그럴지도.

마르코, 자기 소개 좀 해주시겠어요? Node 어떻게 인연을 맺게 되셨나요?

네, 전 확실히 얼리 어답터는 아니에요. Node 8년 전부터 Node 관심을 갖기 시작했죠. 그 전에는 자바를 다루고 있었는데, 항상 이런 생각만 했어요. ‘이 모든 상투적인 코드를 쓰고 싶지 않아’라고요. 정말 지루했거든요. 그리고 당시 Node.js는 가장 신선한 기술이었고, 여전히 최첨단이었죠.

오랜만입니다. 저는 몇 년 전 NearForm에 합류하면서 기여를 시작했습니다. 마테오가 떠난 다음 주에 입사한 것 같네요. 참 우연의 일치였죠. 그 후 저는 자바스크립트 생태계의 보안 문제에 더 깊이 관여하게 되었고, 당시 발생하고 있던 온갖 공격 사례들에 관심을 갖게 되었습니다.

정말 좋네요. 그나저나 마르코는 이제 겨우 스물두 살이죠? 마르코, 넌 정말 어리구나.

아니요, 전 스물여덟 살이에요.

스물여덟. 그래. 정말 어리네.

좋습니다. 최근 Node.js와 관련해 일어나고 있는 모든 일들에 대해 이야기해 보려고 합니다. 그전에 — 저희가 OpenJS와 함께 이번 행사를 주최하게 된 이유 중 하나이기도 한데 — 저희는 지난 몇 년간 OpenJS와 협력해 왔습니다. 사실, 정확히 2년 전 그곳에서 생태계 지속 가능성 프로그램을 시작했죠. 아시다시피, HeroDevs는 수명 주기가 끝난 소프트웨어를 관리하고 있습니다. 그리고 OpenJS는 이 점에 대해 꽤 개방적인 태도를 보이고 있습니다. 우리는 더 많은 혁신과 기여를 원하지만, 동시에 보안과 지속 가능성도 챙기고자 합니다.

저희도 잘 알고 있습니다. 대규모 환경을 운영하는 조직들이 단순히 버전을 업그레이드하거나 다른 버전으로 마이그레이션하는 일이 때로는 얼마나 어려운지, 몇 시간이고 이야기할 수 있을 정도니까요. 호환성 문제나 기타 여러 위험 요소들이 따르니까요. 하지만 최근 Node 지원 종료가 있었습니다. 불과 한 달도 채 되지 않은 지난 4월 30일, 즉 4월 말에, 상당한 사용자 기반을 보유했던 매우 중요한 버전인 Node 지원이 종료되었습니다. 유지보수 종료, 업데이트, 마이너 릴리스, 패치 제공이 모두 중단된 것입니다.

말씀을 끊어서 죄송한데요, 4월에 Node 몇 번이나 다운로드되었는지 아시나요?

지금 당장 npm에 가지는 않을 건데, 말해 봐.

9,500만 번.

그냥 말이야.

여기서 한 가지 말씀드리고 싶은 점은, 대부분의 사람들이 앱, 특히 특정 배포 환경에서 Node.js를 도입한 후에는 전혀 업그레이드를 하지 않는다는 것입니다. Node 채택이 확대됨에 따라 우리가 목격하고 있는 현상은, 많은 기업과 팀이 전혀 업데이트를 하지 않고 있다는 점입니다. 그들에게 Node 업데이트는 매우 큰 Node . 대개 의존성 트리에서 너무 뒤처져 있어 전체 의존성 트리를 업데이트하려면 대규모 리팩토링과 구조 조정이 필요하기 때문입니다. 따라서 작은 단위로 나누어 진행하는 대신, 일괄적인 대규모 업데이트를 수행해야만 합니다.

하지만 맞아요, Node 9천만 건이라는 문턱을 넘지 못하고 있습니다. 솔직히 말해서, 지난 4월 기준으로 Node.js의 월간 다운로드 수가 가장 많았던 시기는 작년 6월이나 7월 무렵으로, 약 1억 2,500만 건 정도였습니다. 마테오 씨가 관련해서 아주 유용한 데이터를 많이 가지고 계시더군요. 차트 몇 개를 봤는데 정말 훌륭하더군요.

네, 다른 화면에 차트가 나와 있어서 사실관계는 정확히 파악하고 있습니다.

마르코, 당신은 그 모든 Node 릴리스의 스크린샷을 저에게 보여줬죠. 그중 대부분은 당신이 직접 릴리스 작업을 담당했잖아요. 그 경험에 대해 이야기해 주세요. 어땠나요?

Node LTS 버전이 되었을 때 출시된 기능 중 약 70%는 저와 다른 자원봉사자들이 담당했던 것으로 기억합니다.

Node 릴리스하는 Node 정말 힘든 Node . 문제가 발생하기 일쑤라 많은 인내심이 필요할 뿐만 아니라, 모르는 부분에 대해서는 여러 사람과 소통하며 도움을 요청해야 하죠. 게다가 정말 많은 노력이 필요합니다. HeroDevs가 제 Node 관련 오픈소스 작업을 후원해 주셔서 기쁩니다. 지속 가능성의 문제 중 하나는 바로 이런 지루하고 때로는 따분한 작업을 수행하는 자원봉사자들에게 자금을 지원하는 것이기 때문입니다. 그리고 이것이 우리가 릴리스 일정을 조정하는 주된 이유 중 하나이기도 하다고 생각합니다.

그 얘기를 한번 해볼까요? Node 주요 소식 중 하나는 릴리스 일정의 변경입니다. 마르코, 먼저 그 부분부터 말씀해 주시겠어요? 그 결정에는 어떤 배경이 있었나요?

자, 우선 잘 모르시는 분들을 위해 말씀드리자면, 저희는 6개월마다 버전을 출시해 왔습니다. 홀수 버전은 LTS가 아니며, 짝수 버전인 18, 20, 22 등이 LTS입니다. 하지만 이제 연간 1회 출시로 변경되며, 모든 짝수 버전이 LTS가 될 예정입니다.

그리고 이 커뮤니티에서 제가 정말 좋아하는 또 다른 점은 모든 것이 정말 투명하게 공개되어 있다는 거죠, 그렇죠? 제가 찾아보니 몇 달 전에 이 주제가 논의되었던 토론 게시판을 발견했어요.

네, 사실 이번 결정의 주된 이유는 네 가지 릴리스를 동시에 유지 관리하는 것—때로는 출시해야 할 릴리스가 네 개나 되기도 하니까요—이, 특히 보안 릴리스의 경우 너무 많은 작업량을 요구하기 때문입니다. 이는 대부분 자원봉사자인 기여자들에게 큰 부담이 됩니다. 또 다른 문제는 유지 관리 작업이 너무 많이 흩어지게 된다는 점입니다. LTS 릴리스는 최신 버전과 너무 달라서 수정 사항을 역포트하기가 매우 어렵습니다. 따라서 이 작업은 자원봉사자들이 감당하기에는 너무 버거운 수준이 될 수 있습니다.

그래서 이런 아이디어가 나왔습니다. 대대적인 변경 사항이 포함된 메이저 릴리스를 너무 자주 내놓는 대신, 릴리스의 범위를 줄여보는 건 어떨까요? 그래서 2027년에는 Node 출시할 예정이며, 이는 홀수 버전 중 최초로 LTS(장기 지원) 버전이 될 것입니다. 이는 매년 단 한 번의 메이저 릴리스만 진행하게 됨을 의미하며, 릴리스 담당자들의 업무를 훨씬 수월하게 만들어 줄 것입니다. 또한 기업들에게도 도움이 될 것이라 생각합니다. 두 번이 아닌 한 번만 메이저 버전을 업데이트하면 되니까요.

마테오, 이에 대해 한마디 하실 말씀이 있으신가요? 그 외에 논의된 다른 안건이 있나요?

그건 그렇고, 27번째 버전이 연도와 일치하게 된다는 점이 참 좋네요. 2028년에 말이죠.

가장 중요한 것은 연도와 일치시키는 것입니다.

따라서 Node LTS가 될 것이며, 2027년에 출시될 Node 역시 LTS가 될 것입니다. 몇 가지 고려할 점이 있습니다. 가장 근본적인 부분은 데이터에서 비롯됩니다. 무엇보다도 이 결정은 실제 데이터를 바탕으로 한 것입니다. LTS가 아닌 릴리스를 사용하는 사람은 아무도 없습니다. 거의 전무합니다. 그러니 의미가 없습니다. 릴리스 담당자들이 이 릴리스들을 내놓기 위해 하는 모든 작업은 극소수의 사람을 위한 것입니다. 게다가 모듈 작성자들은 테스트하고 유지보수해야 할 릴리스들을 갖게 되지만, 그 수명은 고작 6개월에 불과합니다. 다시 말해, 그럴 가치가 전혀 없습니다.

오픈소스 커뮤니티의 모든 프로젝트에서 잘 알려진 사실입니다. 커뮤니티가 공식적인 LTS(장기 지원) 약속을 하면, 사람들은 이를 적극 활용합니다. 도대체 누가 굳이 LTS가 아닌 버전을 선택하겠습니까?

네, 맞아요. 어떤 분들은 새로운 기능을 테스트해 보고 싶어서 그렇게 하기도 하죠. 그리고 새 프로그램의 구조상, 주요 변경 사항이나 호환성 문제를 일으킬 수 있는 변경 사항을 적용할 수 있는 긴 알파 버전이 있습니다. 그러니 최첨단 기능을 먼저 경험하고 싶다면 그 버전을 사용하시면 됩니다. 저희는 여전히 알파 버전을 출시하고 있으니 작업은 계속될 겁니다. 하지만 가장 큰 차이점은, 이러한 알파 버전에는 보안 보장이 없다는 점입니다. 따라서 백포트 작업 같은 건 전혀 필요 없죠. 이는 보안 릴리스에 필요한 작업량을 줄여주는데, 현재 쏟아지는 수많은 유효한 보고서를 고려할 때 이것이 바로 저희가 가장 우려하는 부분 중 하나입니다.

이 대화의 또 다른 핵심 주제는 바로 보안과 취약점 문제입니다. 그 이야기로 넘어가기 전에, 한 가지 더 중요한 점이 있다고 생각합니다. 바로 6개월마다 수많은 새로운 기능이 추가된다는 점입니다. 단순히 CVE를 수정하는 것만이 전부가 아니잖아요? 여러분께 여쭤보고 싶은데요, 어떻게 해내시는 건가요? 자원봉사자도 많고, 끊임없이 새로운 API를 추가하고, 성능도 개선하고 계시는데...

솔직히 말해서, 이 부분을 좀 더 자세히 살펴봅시다. 성능이 향상되고 있나요? 네, 아마도 조금은 그렇겠죠. 하지만 가장 큰 관심사는 하위 호환성을 깨지 않고, 사람들이 업그레이드를 하지 못하는 상황을 최소화하는 것입니다. 그것이 주된 동력입니다. 제가 항상 말하듯이, Node.js를 훨씬 더 빠르게 만들 수는 있겠지만, 그러면 여러 문제가 발생할 것입니다. 더 빨라지길 원하시나요? 그 대가로 얼마나 많은 문제를 감수할 의향이 있으신가요? 그런 문제도 있습니다. 그리고 우리는 Node.js 호환성을 40~50%만 달성해도 일부 사람들에게는 충분하다는 것을 입증했습니다. 실제로 그렇게 하는 프로젝트들도 있고, 문제없이 잘 돌아갑니다. 하지만 현실적으로 대규모 배포 환경을 가진 기업들은 마이그레이션을 하지 않을 것입니다. 어렵습니다. 정말 어렵습니다.

마르코, 또 뭐가 있지?

한 가지 더 말씀드릴 게 있습니다. 사람들이 업그레이드를 하지 않고 있습니다. 새로운 사용자층이 유입될 때마다 Node 사용량은 Node , 그들은 그 버전에서 벗어나지 않고 있습니다. 정말로 사용자층이 양극화되고 있는 셈이죠. 확인해 보니 Node 다운로드 수가 여전히 상당합니다. 매달 2천만 건 정도는 다운로드되고 있죠. 도대체 왜 사람들이 이걸로 테스트를 하는 건지 모르겠습니다. 이건 이제 과거의 유물이나 다름없습니다. 정말 심각한 문제입니다.

기능 측면에서는 계속해서 새로운 기능을 출시하고 있습니다. 하지만 사실 어느 정도는 매우 보수적인 편입니다. 사실 훨씬 더 많은 기능을 출시할 수 있었죠. 팀원들도 훨씬 더 많은 기능을 출시하고 싶어 했지만, 우리는 그들이 실제로 원했던 것보다 조금 더 절제된 선에서 유지하려고 노력했습니다.

마르코, 거기 뭐 덧붙일 게 있니?

정말 믿기 힘든 일이지만, 계속해서 새로운 기능을 추가해 주는 Node.js 커뮤니티의 모든 분들께 찬사를 보냅니다. 현실은 이렇습니다. 하위 호환성을 유지하고 내부 구조에 기반한 레거시 시스템과 프레임워크가 깨지지 않도록 하기 위해 — 우리는 사용자에게 불편을 주지 않으려 노력합니다. 정말 미친 일이죠. 때로는 단순한 주요 변경 사항조차도 너무 많은 사람과 패키지에 영향을 미칠 수 있다는 이유로 기능을 제거하지 않기로 결정하기도 합니다. 진짜 문제는 생태계에 있습니다. 예를 들어, 지난 15년 동안 npm에 올라와 있던 패키지 중 우리가 더 이상 사용하지 않기로 한 내부 기능에 의존하는 것들이 있습니다. 하지만 해당 패키지가 더 이상 유지보수되지 않고 주당 5천만 건의 다운로드가 발생하기 때문에 제거할 수 없습니다. 이것이 바로 Node.js가 매우 보수적인 경향을 보이는 이유입니다. 우리는 수많은 API를 비추천으로 지정하고, 노출된 수많은 레거시 내부 기능을 제거할 수도 있겠지만, 그렇게 할 수 없습니다. 그래서 어떤 메이저 릴리스의 변경 내역을 볼 때마다, 우리는 훨씬 더 많은 것을 비추천으로 지정했어야 했고, 훨씬 더 많은 일을 할 수 있었을 텐데, 그렇게 할 수 없다는 생각이 항상 듭니다.

제가 들은 이야기들은 이 커뮤니티와 이 프로젝트에 대해 제가 이미 알고 있던 점을 다시 한번 확인시켜 줍니다. 정말 잘 운영되는 프로젝트입니다. 모든 자원봉사자분들과 협력자분들, 여러분 모두 정말 훌륭한 일을 하고 계십니다. 그들은 가능한 한 시스템을 망가뜨리지 않으면서도 계속해서 프로젝트를 유지해 나가겠다는 확고한 의지를 가지고 있습니다. 새로운 버전이 나올 때마다 호환성 문제가 발생하거나 더 이상 지원되지 않는 API가 생기겠지만, 확고한 의지가 있습니다. 제 생각에 이것이 바로 Node.js가 성공한 핵심이자 수많은 조직과 애플리케이션이 이를 채택한 이유입니다. 공식적인 프로세스가 마련되어 있고, 장기적인 지원을 위한 확고한 의지가 있기 때문입니다.

자, 이제 보안과 관련된, 음… 딱히 즐거운 주제는 아니지만 흥미롭고 때로는 안타까운 상황에 대해 이야기해 보겠습니다. TSC의 마테오(Mateo)가 최근 발표한 주요 변경 사항 중 하나는 바운티 프로그램의 중단 또는 일시 중지였습니다. 이에 대한 설명이 담긴 블로그 게시물이 있지만, 취약점을 수정하는 절차에는 변함이 없다는 점을 분명히 하면서 청중 여러분을 위해 여기에 댓글을 남겨 주시면 좋겠습니다.

두 가지 문제가 있습니다. 좋아요. 우선, 작년 초부터 취약점을 보고하는 데 사용되는 AI 기반 엉터리 보고서가 엄청나게 쏟아져 나왔습니다. 그 규모가 정말 어마어마했죠. 그래서 몇 가지 사실이 동시에 적용됩니다. Node.js의 취약점을 보고할 때, Node 사용자 전체에 영향을 Node 사실상 서비스 거부(DoS) 공격의 만능 해결책이 될 수 있는 취약점을 발견할 수도 있습니다. 정말 심각한 문제죠. 이것이 우리가 마주할 수 있는 상황 중 하나입니다. 아니면 기술적으로는 취약점이 맞지만, 특정 환경에서만 발생하는 경우도 있습니다. 마치 달과 금성이 일렬로 정렬되어야만 하고, 이를 유발하는 유일한 방법이 오른발로 세 번, 왼발로 세 번 뛰고 마법의 주문을 외우는 것과 같은 경우 말이죠. 이런 종류의 문제들이 보고되고 있습니다.

솔직히 말해서, 이것들은 실제 취약점입니다. 그렇지 않다는 말은 아닙니다. 다만, 기껏해야 아주 사소한 결함일 뿐이며, 더 긴 공격 체인 속에서 악용될 경우 공격자의 침투 범위를 넓힐 수는 있겠지만, 단독으로 볼 때는 그 중요성이 매우 미미하다는 뜻입니다. 그래도 CVE로 등록된 사항이므로 그에 맞게 다루어야 합니다. 하지만 코드베이스에서 이를 찾아내는 데 드는 비용은 거의 제로에 가깝습니다.

그러면 여기서 드는 질문은 이렇습니다. 그들에게 현상금을 걸어야 할까요? 돈을 지불해야 할까요? 저는 돈을 벌기 위해 토큰을 사용해 또 다른 토큰을 생성하고 있습니다. 이렇게 생각해 봅시다. 100유로 상당의 토큰을 써서 현상금으로 1,000유로를 받는다면, 이는 훌륭한 투자입니다. 100달러짜리 구독료가 현상금을 통해 매달 1,000유로로 늘어나는 셈이죠. 사람들은 이걸로 생계를 유지할 수 있습니다.

하지만 이것이 우리가 장려하거나 지속해야 할 일일까요? 만약 이를 후원해 줄 기업이 있다면, 물론 기꺼이 하겠지요. 우리는 우선순위를 정하고 필요한 작업을 수행하는 데 기꺼이 나설 것입니다. 하지만 현실은 더 이상 후원자가 없다는 것이었습니다. 솔직히 말해서, 우리는 그 ‘엉터리’를 멈추고 싶었습니다. 그 ‘엉터리’가 가장 큰 문제였는데, 많은 사람들이 이를 보고서에 전혀 전문성이 없는, 그저 쉽게 돈을 벌 수 있는 수단으로 여겼기 때문입니다. AI와 대화하는 건 괜찮지만, 그 AI가 우리가 목격한 많은 사례들보다 훨씬 더 유능합니다. 우리는 말 그대로 프롬프트를 복사해 보고서 안에 붙여넣은 사례를 실제로 목격했습니다. 제대로 복사해서 붙여넣는 능력조차 없었던 셈이죠.

물론 우리는 AI에 대해 이야기하고 싶습니다. 청중 여러분도 AI에 대해 이야기하고 싶어 하실 겁니다. 하지만 먼저, 마르코, 또 하나 중요한 점은—현상금 프로그램이 중단된다고 해서 보안 신고 절차가 바뀌는 것은 아닙니다. 그 절차는 그대로 유지됩니다.

그 과정을 하나씩 설명해 주실 수 있나요? 접수와 분류 과정 말이에요?

네, 신고 접수는 HackerOne을 통해 이루어집니다. 저희는 HackerOne을 통해 제보를 받습니다. 제보에 대한 선별 작업을 진행하는데, 이는 자원봉사 기반으로 운영되기 때문에 시간이 날 때 선별 작업을 하는 분들이 계십니다. 제보가 너무 많이 들어오고, 현재 제보를 작성하는 데 걸리는 시간과 선별하는 데 걸리는 시간 사이에 불균형이 있어서 이 작업을 하려는 분들이 많지 않습니다. 문제가 사실인지 확인하고 재현하는 데 시간이 꽤 걸리거든요. 그게 가장 큰 문제 중 하나입니다.

하지만 HackerOne을 통해 보고서를 접수하고, 릴리스를 출시할 만큼 충분한 보고가 모이면, 예를 들어 2주 후에 보안 릴리스를 진행할 예정이라는 공지를 올립니다. 그 뒤 비공개적으로 해당 취약점에 대한 패치를 개발합니다. 그리고 업데이트된 버전과 동시에 출시하기 위해 몇 가지 릴리스를 조율해야 합니다. 이것이 가장 어려운 부분인데, 취약점을 수정하는 팀과 릴리스 담당자를 한데 모아 동시에 작업을 진행해야 하기 때문에 두세 명, 때로는 그 이상의 인원을 조율해야 하기 때문입니다. 따라서 보안 릴리스가 있을 때는 할 일이 산더미입니다. 그 2주 동안은 관련된 모든 사람에게 매우 바쁜 시간입니다.

그것이 바로 우리가 일정을 조정한 이유 중 하나입니다. 바로 그 기간 동안 업무 부담을 줄이기 위해서였죠. 물론, 보고서에 정보가 많을수록 좋다는 건 두말할 필요도 없습니다. 이미 해결 방안을 생각해 두셨다면, 그 내용을 모두 보고서에 담아 주세요.

사람들이 수정본을 함께 올리는 경우는 정말 드뭅니다. 대부분은 그럴 수조차 없죠. 대부분의 사람들은 해결책이 있다 해도 굳이 올리지 않습니다. 하지만 저희는 그런 수정본을 환영합니다. 아주 훌륭한 패치가 있는 경우도 있고, 그렇지 않은 경우도 있습니다.

이 프로세스는 잘 작동하지만, 여러 단계가 연쇄적으로 연결되어 있어서 상당히 부담스럽기도 합니다. 저희는 Node.js 조직 내에서 Node 몇 가지 Node 의존성 라이브러리를 보유하고 있습니다. 특히 LLHTTP라는 라이브러리가 있는데, 이는 저희가 개발한 HTTP 파서입니다. 이 HTTP 파서의 릴리스 작업을 진행해야 하는데—참고로 이건 꽤 흥미로운 기술이니, 언젠가 파올로에게 이 얘기를 좀 들어보시는 게 좋을 것 같습니다. 어쨌든, HTTP 파서가 있습니다. 그리고 Fetch에 사용하는 라이브러리인 Undici와 수많은 새로운 WhatWG 기반 API들도 있습니다. 저는 Undici의 주 관리자이며, Node 모든 보안 릴리스마다 수많은 Undici 수정 사항이 반영됩니다. 현재 Node Node , Node , 그리고 현재 활성 버전인 Node , 이렇게 세 가지 LTS 릴리스가 Node , 이 세 가지 모두에 패치를 배포해야 합니다. Node Undici 6을 사용하고 있으며, 다른 버전들은 각자 다른 버전을 사용하고 있습니다.

이 커뮤니티와 기여자, 협력자들이 쏟는 노력은 정말 대단합니다. 게다가 수천, 수만 개의 조직이 자바스크립트, Node.js, 타입스크립트 등을 활용해 실제 운영 시스템을 가동하고 있죠. 그래서 HeroDevs와 같은 기업들은 다시 이 커뮤니티에 기여하고 있습니다. 단순히 도움을 주는 것뿐만 아니라, 커뮤니티의 일원이 됨으로써 많은 전문 지식과 경험을 쌓을 수 있기 때문입니다.

자, 그럼 AI에 대해 이야기해 봅시다. 뭐, 당연히 다들 AI 얘기를 하고 싶어 하니까요. 요즘 새로운 도구들이 엄청나게 많이 나오고 있고, 사람들이 그 AI 쓰레기 같은 것들에서 발견한 취약점을 보고하고 있죠. 하지만 제가 듣기로는, 마르코 씨도 이 주제에 대해 좋은 블로그 글을 쓰셨는데, 단순히 보고하는 것만이 중요한 게 아니라 맥락과 지식이 가장 중요한 요소라고 하더군요. 하지만 저는 실제로 상황이 나아지고 있다는 사실에 대해서도 이야기하고 싶어요. 어쩌면 이제 이런 대규모 언어 모델(LLM)들이 진짜 취약점을 보고해 주고 있을지도 모르죠.

맞아요. 정말 그래요. 진짜 취약점이 발견되고 있어요. 이건 사실이에요. 대규모 언어 모델(LLM)의 기능들 중 대부분은 여전히 단순한 버그에 불과했지만, 이제는 진짜 취약점으로까지 이어지고 있어요. 발생 빈도가 상당히 늘어난 것 같아요. 제가 마지막으로 확인했을 때, 이전에는 50%였던 비율이 66%로 올라간 것 같았어요. 한때는 상황이 정말 심각했지만, 이후 회복되었습니다. 지금까지 보고된 대부분의 사례는 충분히 타당하며 디버깅하기에도 만만치 않은 수준이라고 말하고 싶습니다. 사소한 문제들은 이미 문서화되었습니다. 우리는 보안 MD에 좋은 취약점과 나쁜 취약점을 구분하는 모든 기준을 문서화하는 캠페인을 진행해 왔습니다.

Node.js는 Mitre와 관련이 있나요?

아쉽게도 아직은 아닙니다. 접근 권한을 요청했지만, 아직까지 허가를 받지 못했습니다. 분명 가능해질 거라고 확신합니다. 어차피 주요 오픈소스 프로젝트 중 하나일 테니까요. 하지만 어쨌든, 그 권한이 없더라도 LLM이 보고하는 문제점들은 점차 개선되고 있습니다. 그리고 제가 읽은 내용 중 정말 흥미로웠던 점은, 인간의 능력을 뛰어넘어 여러 취약점을 연쇄적으로 연결해 실제 공격 코드를 만들어낼 수 있다는 점이었습니다.

네, 그게 가장 어려운 부분이에요. 바로 그 점이 참 새로운 점이자, 핵심이 되는 부분이에요. 어떤 경우에는 심각도가 낮거나 중간 수준에 불과한 CVE라도 다른 CVE와 연쇄적으로 결합되면 정말, 정말 심각한 문제가 될 수 있죠.

마르코, 한 가지 여쭤보고 싶은데요. 새로운 CVE가 발표되고 취약점에 대한 수정 패치도 나오지만, 그럼에도 불구하고 HeroDevs의 지원 종료된 버전들에 대해 다시 패치를 적용해야 하잖아요. 그 작업에는 어떤 과정이 포함되나요?

네, 그래서… 제가 Node , Node , Node 다루고 있다고 말하면, 다른 동료들은 “뭐라고?” 하는 반응이에요. 오래된 종속성들 때문에 구버전 Node 다루는 Node 꽤 Node . 또 다른 큰 문제는 이 구버전들이 보안상 얼마나 취약하냐는 점이에요. 이런 일이 자주 발생하죠. 그리고 취약점을 수정하면서 저는 스스로에게 묻곤 해요. '6, 7년 전에는 도대체 어떻게 버텼던 거지?'라고요. 시간이 지나면서 우리는 수많은 취약점과 버그를 발견했거든요. 새로운 보안 패치가 나올 때마다 저는 항상 지원 종료된 버전에도 적용되는지 확인하는데, 대부분 적용되더라고요. 그래서 시간이 흘러도 여전히 구버전에서 버그가 발견되는 거예요. 정말 말도 안 되죠.

청중 여러분께 명확히 말씀드리자면, 장기 지원 종료는 더 이상 업스트림 패치가 제공되지 않는다는 의미입니다. 예를 들어 Node 경우, HeroDevs와 같은 상용 서비스를 이용해야 합니다. 이는 분명 큰 과제이며, 프로젝트가 계속 발전해 나가는 것—솔직히 말해 가능한 한 빠르게 발전해 나가는 것—은 지극히 당연한 일입니다. 물론 이는 마이그레이션과 호환성 문제라는 과제를 동반합니다. 그리고 마테오가 앞서 언급했듯이, 기업과 조직들이 반드시 마이그레이션을 진행하는 것은 아니라는 점을 확인할 수 있습니다. 그들은 18, 20 버전이나 그보다 더 오래된 버전들을 계속 사용하고 있습니다.

마르코, 정말 힘든 작업이었을 텐데, 너와 HeroDevs의 다른 엔지니어들이 그 작업과 테스트에 정말 많은 노력을 기울였지. 사실, 그게 바로 내가 너희들에게 물어보려던 또 다른 질문이었어. 매번 릴리스할 때마다 테스트 작업량이 어마어마할 텐데, 어떻게 해내는 거야?

네. 릴리스 과정에서 가장 어려운 부분은 CI를 통과시키는 것입니다. 정말 다양한 특수 플랫폼에서 수많은 테스트를 수행해야 하거든요. 저희는 ‘Canary in the Goldmine’이라는 시스템을 운영하는데, 여기서 릴리스 후보 버전을 생태계의 npm 패키지와 연동해 테스트함으로써 패키지에 문제가 발생하지 않는지 확인합니다. 몇 시간씩 걸리는 CI 작업이 정말 많아요. 하나라도 실패하면 다시 실행하고 몇 시간을 기다려야 하죠. 꽤 번거롭긴 하지만, 중요한 과정입니다.

결코 지나가지 않는다.

이 문제는 절대 사라지지 않아요. 한때는 정말로 안정성을 높이려고 애썼던 적도 있었죠. 매일 불안정한 테스트가 몇 개나 있는지 보여주는 안정성 보고서를 받는데, 한동안은 그 테스트들을 수정해서 AI에 보고서를 입력해 주곤 했어요. 몇몇 사람들은 PR(プル 리퀘스트)의 품질이 별로라고 불평했지만, 적어도 저는 도움을 주려고 노력하고 있었으니까요. 그러다 그만두게 되었죠. 하지만 문제는 매우 까다로운데, 그 수정 사항들을 적용하는 것조차 어렵기 때문이에요. 결코 간단한 일이 아니거든요.

네, 정말 엄청난 작업량이에요. 릴리스를 준비하는 개발자라면 누구나 공감할 거예요.

마지막으로 한 가지 더 말씀드리고 싶습니다. 최근 런던에서 Node.js 커뮤니티가 모인 모임이 있었습니다. 그곳에서 여러 가지 계획이 논의되었는데, 바로 그때 이번 릴리스 일정 변경이 발표되었습니다. 마르코나 마테오 님, Node.js의 향후 계획에 대해 덧붙이고 싶은 말씀이 있으신가요? 예를 들어 보안 측면에서, CVE 보고 건수 증가에 대응하기 위한 다른 소식이나 변경 사항이 있을까요?

저도 OpenJS 재단의 이사회에 소속되어 있으며, 현재 현상금 프로그램 개발 비용을 지원하겠다고 제안한 여러 업체들과 협력하고 있습니다. 우리는 업체들이 프로그램을 후원하고 대가를 얻을 수 있으면서도, 동시에 유지보수 담당자들이 시간을 투자하는 데도 타당성이 있는 구조를 마련하기 위해 노력하고 있습니다. 만약 비교적 쉽게 해결할 수 있는 문제에 현상금을 걸면, 말 그대로 '일확천금' 식의 계획이 되어버릴 것입니다. 따라서 현상금은 고위험 및 중대한 취약점에 대해서만 적용되어야 할 것입니다.

솔직히 말해서, 그냥 이 거액의 자금을 가지고 토큰을 소각하면서 모든 취약점을 직접 찾아내는 방식일 수도 있습니다. 이제는 숫자 게임이 되어버렸죠. 수백만 명에게 영향을 미칠 수 있는 실질적인 문제를 찾아내는, 진정 탄탄한 연구를 수행하는 연구자들에게는 정말 큰 현상금을 주고 싶습니다. 실제로 그런 사례도 몇 건 있었고, 그중에는 아주, 아주 큰 규모였던 것도 있었습니다. 하지만 대개는 아주 사소한 극단적인 사례들이거나, node CDN이나 로드 밸런서 뒤에 두지 않았을 때만 작동하는 경우인데, 솔직히 말해서 요즘은 누구도 그런 환경을 쓰지 않으니까요.

아니면 누군가가 계속 인스펙터 프로토콜 문제를 신고하고 있는 것 같습니다. 우리는 어디에나 분명히 적어 두었습니다. 인스펙터 프로토콜을 사용한다면, 그 책임은 전적으로 본인에게 있습니다. 이는 개발용 디버깅 도구일 뿐입니다. 프로덕션 시스템에서 이 기능을 열어두지 마십시오. 그런데도 사람들은 계속해서 이를 공격 시나리오로 보고하고 있습니다. 하지만 말 그대로, 이 기능을 보안할 수 없습니다. 보안할 방법이 없습니다. 말 그대로 누군가가 해당 node 장악할 수 있도록 설계된 것이기 때문입니다. 불가능한 일입니다.

예전에 앱 보안 업무를 주로 맡았을 때, 저는 발표에서 이렇게 말하곤 했습니다. “보세요, 세상에는 수백만 개의 취약점이 존재합니다. 문서화된 익스플로잇에 더 주의를 기울이세요.” 하지만 그런 것들조차 대개는 사소한 경우가 많습니다.

지난 보안 세션에서 제가 다뤘던 Undici의 취약점에 대해 이야기해 보겠습니다. Node.js에는 사양에 기반한 WebSocket 구현체가 포함되어 있습니다. 훌륭한 표준은 아니지만, 그건 별개의 주제입니다. 어쨌든, WebSocket 표준은 패킷 압축 기능을 제공합니다. WebSocket 패킷은 TCP 위에 자체 프레임 구조를 갖기 때문이죠. 즉, HTTP, WebSocket, 그리고 그 위에 자체 프레임 구조가 얹혀 있는 형태입니다. 그리고 이 패킷들을 압축할 수 있습니다. 저는 그 사실을 몰랐지만, 저희는 이 기능을 지원합니다.

알고 보니, 누군가가 Node.js를 사용해 여러분이 어떤 이유로든 신뢰하지 않는 원격 WebSocket 인스턴스에 연결하면, 그 서버는 서비스 거부(DoS)를 유발하고 앱을 다운시키는 ‘실버 불릿’ 패킷을 보낼 수 있습니다. 예를 들어, 100킬로바이트 크기의 패킷이 메모리 내에서 100기가바이트로 팽창하면서 앱이 다운되는 식이죠. 정말 식은 죽 먹기입니다.

그런 점이 있었습니다. 그리고 또 다른 측면은 — 여전히 Undici에 대해 이야기하고 있는 중인데 — 이 기능이 사용자가 명시적으로 활성화해야만 하는 기능이라는 점입니다. 실험적인 기능을 활성화하고 이를 수동으로 지원하는 코드를 작성해야만 이 취약점을 이용할 수 있습니다. 따라서 한쪽 끝에서는 악용하기 어렵다는 점이 있습니다. 원격 WebSocket 서버를 입력으로 받아들이는 WebSocket에 연결되는 애플리케이션이 필요하기 때문에, 적용 범위가 매우 제한적입니다.

정말, 정말 많은 세부 사항들이죠. 제게 있어 이 프로젝트와 모든 자원봉사자들이 이 생태계에 기여하는 가치는 바로 그런 점에 있습니다.

질문들을 대충 훑어봤는데, 다 다룬 것 같습니다. AI에서 비롯되는 취약점의 유형에 대한 질문도 있었죠. 마지막으로 한 마디만 덧붙이자면, 즐거운 시간은 정말 순식간에 지나가네요. 이 주제로만 해도 두세 시간은 더 이야기할 수 있었을 겁니다.

청중 여러분께서 이번 세션을 유익하게 여기셨기를 바랍니다. 앞으로도 이와 같은 웨비나를 계속 진행할 예정입니다. 다시 한 번 말씀드리자면, HeroDevs는 OpenJS 재단 생태계 지속 가능성 프로그램의 창립 회원사입니다. 저희는 오픈소스 커뮤니티를 지원하는 한편, 지원 종료된 Node 버전을 여전히 사용 중인 기업들을 위한 비즈니스도 운영하고 있습니다. 버전 12부터 지원을 제공하고 있습니다. 마르코, 맞나요?

열두 살, 열네 살, 열여섯 살, 열여덟 살, 그리고 이제 스무 살.

또한, 지원 종료일 전에 미리 대비하고자 하는 고객들을 위해, 지원 종료 예정인 22 및 24 버전의 맞춤형 버전도 제공하고 있습니다.

훌륭합니다. 마테오 씨와 마르코 씨, 오늘 함께해 주셔서 정말 감사합니다. 시간 내주셔서 진심으로 감사드립니다. 앞으로도 계속 이야기를 나누고 싶네요. 시청해 주신 모든 분들께도 감사드립니다. 안녕히 계세요, 여러분. 안녕히 계세요.

AI로 요약하기
호스트
하비에르 페레즈
날짜
2026년 5월 27일
기간
50분