한화비전 카메라 펌웨어에 GitHub 관리자 토큰이 들어간 이유

한화비전 보안 카메라의 웹 관리 화면을 구성하는 펌웨어 파일에서 GitHub 관리자 토큰이 발견됐어요. 연구자가 확인한 토큰은 조직 내 수백 개 저장소에 관리자 권한을 갖고 있었어요. 원인은 Vite 자체보다 빌드 설정에 있었어요. CI 작업의 환경 변수 전체를 웹 결과물에 넣으면서 외부에 나가면 안 될 자격 증명까지 함께 묶였어요. 1
핵심 요약
| 구분 | 확인된 내용 | 실무에서 볼 점 |
| 노출 범위 | 웹 관리 UI 파일 약 30개에서 같은 GitHub 토큰이 나왔어요 | 같은 비밀이 여러 결과물에 복제되면 폐기 전까지 노출 지점이 늘어나요 |
| 권한 | 토큰이 조직 내 수백 개 저장소의 관리자 권한을 갖고 있었어요 | 제품 빌드용 자격 증명에는 필요한 저장소와 작업만 허용해야 해요 |
| 빌드 원인 | Vite 빌드 변수에 `process.env` 전체를 넣었어요 | 공개 번들에 들어갈 변수는 허용 목록으로 제한해야 해요 |
| 조사 범위 | 약 500개 펌웨어 중 62%를 추출했고, 토큰이 나온 3개에는 모두 같은 값이 있었어요 | 한 모델의 실수보다 공통 빌드 경로를 먼저 점검해야 해요 |
| 대응 | 신고 뒤 12시간 안에 토큰이 폐기됐어요 | 폐기와 함께 접근 기록, 파생 자격 증명, 재발 방지 설정도 확인해야 해요 |
1. 카메라 웹 화면에 CI 환경 전체가 섞였어요
연구자는 한화비전 사이트에 공개된 카메라 펌웨어를 내려받아 내부 파일을 조사했어요. 첫 번째 압축을 푼 뒤에도 암호화된 루트 파일 시스템이 남아 있었어요. `fwupgrader` 바이너리를 분석하자 AES 키를 정적 데이터와 XOR 연산으로 섞어 실행 중 복원하고, `openssl`로 파일 시스템을 해독하는 흐름이 확인됐어요. 키와 IV는 같은 모델군에서 공통으로 쓰였어요. 2
루트 파일 시스템을 추출한 뒤 TruffleHog로 비밀 정보를 검사했어요. 그 결과 웹 관리 UI를 이루는 파일 약 30개에서 같은 GitHub 토큰이 반복해서 나왔어요. 연구자가 권한을 확인했을 때 이 토큰은 한화의 GitHub 조직에 속한 수백 개 저장소를 관리할 수 있었어요.
토큰이 여러 파일에 들어간 경로도 드러났어요. 카메라 UI는 Vite로 빌드됐고, 한 빌드 변수가 `process.env` 전체를 가리키고 있었어요. 브라우저에서 쓸 값만 고르지 않고 CI 작업의 환경을 통째로 직렬화한 셈이에요. `GITHUB_NPM_TOKEN`뿐 아니라 Kubernetes 서비스 정보와 내부 경로 같은 설정도 결과 파일에 남았어요.
펌웨어 암호화는 비밀 유출을 막지 못했어요
펌웨어를 암호화했어도 제품 안에 복호화 코드와 공통 키가 함께 있으면 분석을 늦추는 정도에 머물 수 있어요. 이번 조사에서는 `fwupgrader`의 난독화된 키 복원 절차를 따라 실제 루트 파일 시스템까지 열 수 있었어요. 배포 결과물에 자격 증명이 없어야 한다는 원칙을 암호화로 대신할 수 없는 이유예요.
연구자는 약 600개 카메라 모델 가운데 내려받을 수 있는 펌웨어 약 500개를 모았어요. 같은 방식으로 62%를 추출했고, GitHub 토큰이 나온 펌웨어는 3개였어요. 세 펌웨어에는 모두 같은 토큰이 들어 있었어요. 일부 제품에서만 보였지만 공통 토큰과 공통 빌드 설정이 연결돼 있었기 때문에, 개별 파일 삭제보다 빌드 경로 수정이 더 중요해요.
실제 카메라에서 토큰이 전송됐는지는 확인되지 않았어요
연구자는 해당 카메라를 가지고 있지 않았어요. 그래서 로그인 페이지를 열 때 토큰이 브라우저로 실제 전송됐는지까지 시험하지 못했어요. 토큰이 펌웨어 디스크에만 있었고 웹 서버가 해당 파일을 제공하지 않았을 여지도 남아 있어요. 공개된 분석으로 확정할 수 있는 범위는 배포 펌웨어에 관리자 권한 토큰이 포함됐다는 사실까지예요.
환경 변수에서 미국 국방부에 할당된 IP 주소도 발견됐지만 용도는 확인되지 않았어요. 내부망에서 임의 주소로 썼는지, 다른 조직과 공유한 CI 구성에서 들어왔는지 알 수 없어요. 이 부분을 사업 관계나 외부 통신의 증거로 해석하면 안 돼요.
신고 뒤 대응은 빨랐어요. 연구자가 토큰의 위치를 식별할 수 있는 정보를 보낸 뒤 한화비전은 12시간 안에 답했고, 토큰을 폐기했어요. 다만 토큰 폐기만으로 확인이 끝나는 것은 아니에요. 유효했던 기간의 접근 기록을 살피고, 관리자 권한으로 만들어진 키나 릴리스가 없는지 확인해야 해요.
왜 중요한가요
브라우저용 빌드는 누구나 읽을 수 있는 공개 결과물로 봐야 해요. 변수 이름에 `SECRET`이 붙지 않았거나 화면 코드에서 직접 참조하지 않더라도, 번들에 들어간 값은 사용자가 내려받을 수 있어요. 프런트엔드 도구가 허용한 설정과 공개해도 안전한 설정은 같은 뜻이 아니에요. 2
재발을 막으려면 공개 변수의 허용 목록을 짧게 유지해야 해요. `process.env` 전체를 객체에 넣는 코드와 광범위한 `define` 설정은 빌드 단계에서 막는 편이 좋아요. 생성된 JavaScript, 소스맵, 펌웨어 이미지를 대상으로 시크릿 스캔도 돌려야 해요. 소스 저장소만 검사하면 빌드 과정에서 새로 섞인 값은 놓칠 수 있어요.
토큰 권한도 줄여야 해요. 패키지를 읽는 작업에 조직 전체 관리자 권한을 주면 작은 빌드 실수가 저장소 전반의 사고로 번질 수 있어요. 저장소 범위가 제한된 짧은 수명의 토큰이나 작업별 자격 증명을 쓰고, 제품 서명과 배포 계정도 분리하는 편이 안전해요.
IoT 제품은 한 번 출하하면 펌웨어가 고객사와 유통망에 오래 남아요. 서버의 환경 변수를 지우는 것만으로 이미 배포된 파일이 사라지지 않아요. 어느 버전에 값이 들어갔는지 찾아 폐기 대상을 정하고, 수정 펌웨어를 배포한 뒤 이전 이미지의 다운로드 경로와 캐시까지 점검해야 해요.
참고 자료
'IT & AI' 카테고리의 다른 글
| AI가 코딩을 빠르게 해도 소프트웨어가 나빠지는 이유 (0) | 2026.07.25 |
|---|---|
| 오픈 웨이트 AI 규제에 빅테크 25곳이 제동을 건 이유 (0) | 2026.07.25 |
| Claude 5 시대, 긴 지침보다 필요한 맥락을 제때 꺼내야 해요 (1) | 2026.07.25 |
| Claude Opus 5 출시, Fable급 성능을 절반 비용에 겨냥했어요 (0) | 2026.07.25 |
| OpenAI와 Anthropic이 중국 오픈 웨이트 AI를 함께 경계하는 이유 (0) | 2026.07.25 |