TECH 으로 돌아가기
TECH HACKER NEWS 오늘 9분 읽기 24 READS

조용한 펌웨어 업데이트가 깨뜨린 Tapo 연동, 새 프로토콜 지원으로 우회하다

수개월째 TP-Link Tapo 플러그를 켜고 끄던 스크립트가 어느 날 갑자기 403 Forbidden을 돌려준다. 코드는 한 줄도 바뀌지 않았는데, 플러그가 조용히 펌웨어를 올린 것이 원인이다. 범인은 Tapo 앱의 Me > Third-Party Services에 숨어 있는 'Third-Party Compatibility'라는 스위치다. 펌웨어 1.4.0부터 플러그는 이 스위치가 켜져 있을 때만 예전 방식으로 서드파티 클라이언트와 대화한다. 비공식 Rust/Python 클라이언트인 tapo 저장소에는 #441, #449, #473을 포함해 같은 증상의 이슈가 최소 아홉 건 올라왔다.

이 라이브러리의 v0.11.1은 바로 이 스위치를 꺼둔 채로도 동작하도록 만든 것이 핵심이다. 약 넉 달에 걸친 작업이 일주일 안에 세 번의 릴리스로 떨어졌다. 9월 28일 v0.10.0, 10월 2일 v0.11.0, 10월 4일 v0.11.1이다. Python 패키지는 Rust 크레이트를 얇게 감싼 래퍼라 모든 변경이 동일한 버전 번호로 양쪽에 동시에 반영된다. 실무자가 유념할 점은, 이것이 3년 사이 세 번째로 서드파티 접근이 조용히 막힌 사례라는 사실이다.

세 번 반복된 '보안 강화'의 패턴

2023년 2월, 카타니아 대학과 로열 홀러웨이 소속 연구자 세 명이 L530E 전구를 시작으로 Tapo 기기와 앱 사이 통신에서 네 가지 결함을 보고했다. 근처에 있는 공격자가 피해자의 Tapo 계정을 탈취하고 Wi-Fi 비밀번호까지 알아낼 수 있는 문제였다. 몇 달 뒤 펌웨어 업데이트가 기존 AES 프로토콜을 KLAP으로 교체하기 시작했지만, TP-Link는 두 사건의 연관성도, 변경 자체도 공지하지 않았다. 2024년에는 카메라 차례였다. Home Assistant 연동을 관리하는 Juraj Nyíri가 취약점을 제보했고, TP-Link는 이를 고치면서 4월경 새 펌웨어 카메라에서 연동 로그인을 막아버렸다. Nyíri가 만든 우회책은 코드 검토 끝에 배포를 거절당했고, 대신 12월에 나온 것이 바로 옛 로컬 로그인을 되살리는 Third-Party Compatibility 토글이었다.

2025년 10월, 펌웨어 1.4.0은 TPAP라는 또 다른 새 프로토콜을 들고 와 플러그를 같은 스위치 뒤에 세웠다. 전구는 2026년 상반기 펌웨어 1.4.1~1.4.3에서 뒤따랐다. 이번에는 탈출구가 문이 닫히기 전부터 있었지만, 그 스위치는 기본값이 꺼짐이었다. TP-Link의 FAQ는 이 기능이 '보안을 위해 기본 비활성화'되어 있으며 켜면 '기기 보안이 약해질 수 있다'고 설명한다. 포럼에서 플러그가 멈췄다고 호소한 사용자들은 Home Assistant가 공식 지원 플랫폼이 아니라는 답을 들었고, TPAP 자체는 끝내 문서화되지 않았다.

꺼둘 이유가 생긴 스위치

최근 펌웨어에서 이 스위치는 기기가 어떤 프로토콜을 쓸지 결정한다. 전구, 플러그, 멀티탭, H100 허브는 스위치가 켜지면 KLAP을, 꺼지면 TPAP를 쓴다. 카메라는 애초에 KLAP을 쓴 적이 없고 더 오래된 AES SSL을 쓰는데, 일부 모델은 스위치가 꺼지면 그마저 거부한다. v0.11.1이 TPAP를 구현하면서 IP 직접 연결이든 discover_devices든 스위치를 끈 상태로도 기기에 접근할 수 있게 됐다. 클라이언트가 기기가 쓰는 프로토콜을 스스로 판별해 로그인하므로 코드 수정은 필요 없다. 반대로 v0.11.0은 오래전 어떤 펌웨어에도 실리지 않게 된 원조 AES 프로토콜을 제거했다. 카메라와 카메라 허브가 쓰는 AES SSL은 그대로 남는다.

스위치를 무시할 수 있다는 편의보다 더 의미 있는 것은 TPAP의 로그인 방식이다. KLAP은 평문으로 오가는 두 개의 난수와 자격증명으로 만든 해시를 교환해 양쪽이 비밀번호를 안다는 사실을 증명한다. 비밀번호 자체는 전송되지 않지만, 로그인 한 번을 캡처한 공격자는 그것을 가져가 하드웨어가 허락하는 속도로 오프라인 비밀번호 추측을 시도할 수 있고, 세션 키가 같은 재료에서 나오기 때문에 추측이 맞으면 이후 통신까지 복호화된다. TPAP는 RFC 9383의 SPAKE2+, 즉 비밀번호 인증 키 교환을 쓴다. 다만 스위치가 켜져 있는 동안 전구나 플러그는 여전히 KLAP을 광고하므로, 이 이점은 스위치를 꺼야 발생한다. 네트워크의 다른 무엇도 호환 스위치를 필요로 하지 않는다면 이제 꺼둘 명분이 생긴 셈이다.

카메라 허브와 플러그 스케줄

TPAP 외에 두 가지가 더 들어왔다. v0.10 이전까지 다룰 수 있는 허브는 H100뿐이었는데, 이번에 H200과 H500 카메라 허브가 추가됐다. 이들은 H100처럼 센서·스위치와 페어링하면서 카메라와도 짝을 이뤄 녹화를 저장한다. ApiClient의 h200·h500으로 핸들러를 만들고 discover_devices로도 찾을 수 있다. 센서와 스위치는 get_child_device_list와 t100, t31x 같은 타입별 자식 핸들러로 H100과 동일하게 다루며, 새로운 부분은 녹화다. 허브에 연결된 카메라 목록과 녹화가 있는 날짜, 특정 시간 구간의 녹화를 조회하고 재생 가능한 MPEG-TS 클립으로 내려받을 수 있다. download_recording은 임의의 AsyncWrite로 쓰고 Python에서는 파일 경로를 받으며, 모든 시각은 UTC다. 저자가 두 허브를 보유하지 않아 @dominiquefournier가 H200으로 약 서른 차례, @supermimai가 H500으로 테스트해준 것이 전제가 됐다.

플러그 스케줄과 타이머도 v0.10부터 PlugHandler와 PlugEnergyMonitoringHandler에 올랐다. 스케줄 규칙은 하루 중 특정 시각이나 일출·일몰 기준 오프셋에 한 번 혹은 지정한 요일마다 작동하며, 규칙이 플러그 안에서 자체 시계로 동작하기 때문에 스크립트나 서버, 인터넷 연결이 끊겨도 유지된다. clock_once·sunrise_once·sunset_once로 일회성 규칙을, get_max_schedule_rules로 남은 여유를 확인하는 식이다. 타이머는 1초에서 24시간 사이 단일 카운트다운을 걸어 플러그를 켜거나 끄며, 한 번에 하나만 무장된다. 한편 MCP 서버인 tapo-mcp는 v0.5.3에서 H200·H500과 스위치를 끈 기기를 지원하지만, 플러그 스케줄·타이머·녹화 다운로드는 아직 라이브러리 전용이다. v0.9에서 올라올 때는 레거시 AES 제거, 트리거 로그·온도 기록 필드명 변경, Python 열거형이 더는 정수와 같다고 비교되지 않는 점 등 몇 가지 호환성 깨짐이 있으니 체인지로그 확인이 필요하다.

SOURCE · HACKER NEWS
원문 전체 보기 → https://mihai.dinculescu.dev/posts/tapo-speaks-tpap/
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기 →
처리 중...