ESPHome web_server 컴포넌트의 Basic Auth 우회 취약점 탐지 템플릿을 작성해
projectdiscovery/nuclei-templates에 Merge됐다.
PR: #13622 — Hacktoberfest 기여

취약점 개요

CVE-2025-57808은 ESPHome 2025.8.0의 ESP-IDF 플랫폼에서 발생하는 HTTP Basic Auth 우회 취약점이다. CVSS 8.1 (High)를 받았다.

ESPHome은 ESP32, ESP8266 기반 스마트홈 기기 펌웨어를 개발하기 위한 오픈소스 프레임워크다. Home Assistant와 연동해서 IoT 기기를 제어하는 데 널리 쓰인다. web_server 컴포넌트를 활성화하면 브라우저에서 기기를 제어할 수 있고, OTA(Over-The-Air) 펌웨어 업데이트도 이 웹 서버를 통해 이루어진다.

문제는 인증 로직에 있었다.


취약점 원인: strncmp vs strcmp

취약점은 AsyncWebServerRequest::authenticate 함수 내부에 있다. 인증 자격증명 비교에 strncmp를 사용하는데, 비교 길이 파라미터가 사용자가 공급한 Authorization 헤더에서 파생된다.

strncmp는 지정한 길이만큼만 비교한다. 그 길이를 공격자가 제어할 수 있다는 게 문제다.

비교 길이가 사용자 입력에서 나오기 때문에 부분 문자열 비교가 가능해진다. 즉 공격자가 올바른 base64 인코딩된 username:password 문자열의 접두사에 해당하는 값을 제공하면 인증을 통과할 수 있다.

실제 예시로 보면 이렇다. 올바른 자격증명이 user:somereallylongpass라면 base64로 dXNlcjpzb21lcmVhbGx5bG9uZ3Bhc3M=이 된다.

클라이언트가 dXNlcjpz (user:s)만 제공해도 인증을 통과한다. 더 나아가 빈 문자열을 제공하면 사용자 이름을 전혀 알지 못해도 인증이 통과된다.

bash

# 정상적인 401 응답
curl -D- http://esphome-device.local/
# HTTP/1.1 401 Unauthorized

# 빈 Authorization 헤더로 인증 우회
curl -D- -H 'Authorization: Basic ' http://esphome-device.local/
# HTTP/1.1 200 OK

이 취약점은 ESP-IDF web_server의 Basic Auth 지원을 사실상 무력화하며, 사용자 이름이나 패스워드에 대한 정보 없이 같은 로컬 네트워크의 다른 기기에서 인증을 우회할 수 있게 한다.

OTA가 활성화된 상태라면 공격자가 악성 펌웨어를 기기에 올릴 수 있다.

패치는 단순하다. strncmpstrcmp로 교체해서 전체 문자열을 비교하도록 수정했다.


템플릿 설계

이 취약점의 탐지 로직은 두 단계로 구성했다.

Step 1: 인증이 활성화된 ESPHome인지 확인

yaml

- method: GET
  path:
    - "{{BaseURL}}"
  matchers:
    - type: dsl
      dsl:
        - 'status_code == 401'
  internal: true

401이 반환되어야 web_server에 인증이 설정된 상태임을 알 수 있다. 인증이 없는 ESPHome이라면 이 단계에서 걸러진다.

Step 2: 빈 Authorization 헤더로 우회 시도

yaml

- raw:
    - |
      GET / HTTP/1.1
      Host: {{Hostname}}
      Authorization: Basic
  matchers:
    - type: dsl
      dsl:
        - 'status_code == 200'
        - 'contains(body, "Dashboard - ESPHome")'
      condition: and

Authorization: Basic — 값이 비어있는 헤더를 보낸다. 응답이 200이고 본문에 "Dashboard - ESPHome"이 포함되면 인증 우회가 성공한 것이다.

raw 방식을 쓴 이유는 일반적인 HTTP 요청 방식으로는 빈 Authorization 헤더를 정확히 표현하기 어렵기 때문이다. raw HTTP 요청으로 직접 헤더를 제어했다.

탐지 흐름 전체는 flow: http(1) && http(2) — 두 단계가 모두 성공해야 취약으로 판정한다. Step 1에서 401이 아닌 서버는 점검 대상이 아니라고 판단하고 멈춘다.


리뷰 과정과 재현 환경 문제

이번 PR은 이전 CVE-2025-49596 기여와 다르게 진행됐다. pussycat0x maintainer가 debug 데이터를 요청했는데, 이 취약점을 재현하려면 실제 ESP32 보드가 필요했다.

그래서 샀다...

pussycat0x: "we're currently facing a few challenges in validating it. Could you please share the debug data?"
ye11oc4t: "this CVE/template needs esp32 board for reproduction(to run server). I will add debug data and configuration here"

IoT 기기 취약점 탐지 템플릿의 특수한 어려움이다. 일반적인 웹 취약점은 Docker 컨테이너나 VM으로 재현 환경을 만들 수 있지만, 펌웨어 취약점은 물리적인 하드웨어가 필요하다. 결국 DhiyaneshGeek이 직접 검증하고 승인해서 10월 19일에 머지됐다. Hacktoberfest 기여 라벨도 붙었다.


ESPHome 사용자라면

web_server와 인증을 함께 사용하고 ESP-IDF 프레임워크를 쓰고 있다면, 최소 ESPHome 2025.8.1로 업데이트해야 한다.

yaml

# esphome configuration
esphome:
  name: my-device

# 업데이트 후 확인
# esphome version: 2025.8.1 이상

즉시 업데이트가 불가능하다면 web_server 컴포넌트를 비활성화하는 게 임시 방편이다. 특히 OTA가 활성화된 기기는 우선순위를 높여서 패치해야 한다.


두 번째 Nuclei 템플릿 기여였다. 첫 번째(CVE-2025-49596, MCP Inspector RCE)는 클라우드/AI 툴링 영역이었고, 이번엔 IoT/임베디드 영역이었다. 재현 환경 문제 때문에 리뷰 과정이 달랐는데, 물리 하드웨어가 필요한 취약점 탐지 템플릿을 오픈소스로 기여하는 게 생각보다 까다롭다는 걸 알게 됐다.


PR: projectdiscovery/nuclei-templates #13622
CVE: NVD CVE-2025-57808
Advisory: GHSA-mxh2-ccgj-8635

Merge됐다! Hacktoberfest 라벨도 받았다.