기술

신뢰하는 소프트웨어에 악성 코드가 스며드는 공급망 공격의 원리

Susan Hill

공급망 공격은 당신이 쓰는 소프트웨어에 침입하지 않는다. 그 소프트웨어를 이루는 부품 가운데 하나를 오염시키고, 평범한 업데이트 과정이 그것을 당신의 기기까지 실어 나르기를 기다린다. 앱은 깔끔하게 설치되고, 서명도 여전히 들어맞으며, 업데이트도 공식 경로로 도착한다. 악성 코드는 그것에 올라타 함께 들어온다. 바로 이 뒤집힘이 이 수법을 그토록 효과적으로 만든다. 소프트웨어를 굴러가게 하는 신뢰를, 그대로 악용되는 지점으로 바꿔 버리기 때문이다.

오늘 당신이 실행하는 것 가운데 화면에 이름이 적힌 회사가 통째로 작성한 것은 거의 없다. 앱 하나가 수백, 수천 개의 오픈 소스 패키지를 끌어들이고, 그 하나하나를 낯선 사람들이 관리하며, 또 저마다 다른 패키지를 뒤에 달고 온다. 개발자가 그 코드를 읽는 일은 드물다. 그들은 코드가 온 레지스트리와 거기 붙은 버전 번호를 신뢰한다. 그 사슬의 어느 고리든 파고든 사람은 하류에 있는 모두에게 한 번에 닿는다. 그래서 오염된 부품 하나가 누군가 알아채기도 전에 수만 개의 프로젝트에 영향을 줄 수 있다.

침입 경로는 몇 가지 유형으로 모인다. 타이포스쿼팅은 인기 있는 이름에서 자판 하나 차이 나는 이름으로 악성 패키지를 깔아 두고 오타를 기다린다. 의존성 혼동은 빌드 도구가 이름을 해석하는 방식을 노려, 회사의 비공개 패키지 대신 공개 패키지를 집어 오도록 속인다. 계정 탈취는 진짜 관리자의 자격 증명을 가로채 악성코드를 평범한 업데이트처럼 배포한다. 2026년 초, 널리 쓰이는 패키지 axios는 주 관리자의 컴퓨터가 사회공학으로 뚫린 뒤 짧은 시간 동안 변조된 버전을 배포했다. 그리고 빌드 파이프라인 오염은 소프트웨어를 조립하고 배포하는 자동 시스템을 노린다. 망가진 단계 하나가 그것에 의존하는 모든 프로젝트에 닿는다.

빌드 파이프라인이 가장 탐나는 표적이 된 것은 바로 다른 모든 것의 상류에 자리하기 때문이다. 인기 있는 GitHub Actions 구성요소 tj-actions/changed-files가 2025년에 침해됐을 때, 공격자들은 그 버전 태그를 악성 코드를 가리키도록 다시 써서, 이만 개가 넘는 저장소의 빌드 로그에서 비밀을 뽑아냈다. 접근 키와 토큰, 개인 키가 모두 평문 그대로였다. 연구자들이 Megalodon이라 이름 붙인 이후의 공격은 GitHub Actions를 스스로 퍼지는 뒷문으로 바꿔 약 여섯 시간 만에 5,561개 저장소에 닿았다. 당신의 소프트웨어를 만드는 기계는 소프트웨어 자체만큼이나 쉽게 무너뜨릴 수 있다.

개발자가 매일 쓰는 도구도 영향권 안에 있다. 2025년 말에 처음 발견된 GlassWorm은 OpenVSX와 마이크로소프트 마켓플레이스에서 Visual Studio Code 확장을 통해 퍼졌다. 보이지 않는 Unicode 문자로 페이로드를 숨겨, 악성 줄이 편집기에서 말 그대로 읽히지 않은 채 사람의 검토를 빠져나갔다. 일단 설치되면 npm, GitHub, Git의 자격 증명을 훔쳐, 그것으로 더 많은 패키지와 확장을 자동으로 감염시켰다. 웜을 규정짓는 특성이다. 편집기는 확장을 배경에서 조용히 업데이트하므로, 피해자들은 아무것도 클릭하지 않고 오염된 버전을 받았다. 또 다른 오염된 VS Code 확장은 GitHub 자체의 내부 저장소 약 3,800개를 훔치는 데 쓰였다.

이 공격들을 잡기 그토록 어렵게 만드는 것은 단계 하나하나가 따로 보면 정당해 보인다는 점이다. 패키지에는 서명이 있다. 업데이트는 진짜 레지스트리에서 온다. 관리자 계정도 진짜다. 전통적 방어는 이미 악성으로 알려진 파일과 빤히 보이는 악성코드를 찾지만, 공급망 공격은 신뢰받고 예상되며 흔히 보이지 않는 코드 속에 숨어, 소프트웨어가 도착해야 할 바로 그때 그 방식으로 도착한다. 더 나쁜 것은, 즉시 업데이트하라는 오래된 보안 조언이 바로 공격자가 기대는 메커니즘이라는 점이다. 처음으로, 최신 버전을 설치하는 것이 무조건 안전한 선택은 아니게 됐다.

방어하는 쪽은 효과 있는 몇 가지 관행으로 모여 왔다. 잠금 파일은 모든 의존성을 정확하고 검증된 버전에 고정해, 설치 도구가 그저 최신이 아니라 검토된 것만 가져오게 한다. 자동 설치 스크립트를 끄면 악성 패키지가 도착하는 순간 코드를 실행하는 가장 흔한 길이 끊긴다. GitHub Actions를 움직이는 태그가 아니라 특정 커밋 해시에 고정하면 태그를 다시 쓰는 수법이 무력해진다. 소프트웨어 자재 명세서, 곧 빌드 안의 모든 구성요소를 적은 상세 목록이 있으면, 다음 사건이 공개될 때 팀은 자신이 노출됐는지 몇 분 안에 안다. 최근 공격을 피한 조직 다수는 별난 일을 하지 않았다. 그저 커밋된 잠금 파일에서 빌드하고, 갓 게시된 패키지를 격리하는 레지스트리 프록시 뒤에서 작업했을 뿐이다.

코드를 쓰지 않는 사람에게 보호는 대체로 간접적이지만, 교훈은 그렇지 않다. 소프트웨어 공급망은 이제 최전선의 전장이며, 그것을 지키는 일은 당신의 휴대폰과 노트북의 앱을 만드는 회사들의 몫이다. 합리적인 대응은 공포도, 알림이 뜰 때마다 모든 것을 업데이트하던 옛 반사 신경도 아니다. 무엇을 내놓고 어떻게 만드는지 공개하는 팀의 소프트웨어를 택하는 것이며, 신뢰할 수 있는 출처를 사슬을 따라 저절로 내려오는 속성이 아니라 고리마다 얻어 내야 하는 것으로 다루는 것이다.

업계의 답은 출처를 중심으로 모양을 갖춰 가고 있다. 코드 한 조각이 어디서 왔고 어떻게 만들어졌는지를 암호로 증명하고, 무엇이든 설치하기 전에 자동으로 확인하는 것이다. 한 세대 전 웹 트래픽을 지킨 바로 그 발상을, 이번에는 소프트웨어 자체의 조립 라인에 적용한 셈이다. 그 증명이 보편화되기 전까지, 모든 설치는 끝내 만날 일 없는 사람들에 대한 신뢰의 행위로 남는다.

토론

댓글 0개가 있습니다.