CVE-2026-75337 (Yu AI Code Mother 경로 탐색) 분석
CVE · 웹·서버 · 경로 탐색 · CVE-2026-75337 [표준]
개요
Yu AI Code Mother는 Spring Boot 3와 LangChain4j로 만들어진 오픈소스 AI 코드 생성 플랫폼입니다(업스트림 저장소 liyupi/yu-ai-code-mother, 개발자 통칭 程序员鱼皮). 사용자가 프롬프트로 코드를 생성하면 그 결과를 브라우저에서 바로 미리 볼 수 있는데, 이 미리보기를 담당하는 정적 리소스 서빙 엔드포인트가 이번 취약점의 무대입니다. 이 엔드포인트는 요청 URL에 담긴 경로를 서버의 미리보기 루트 디렉토리 경로에 정규화 없이 이어 붙입니다. ../ 같은 상위 이동 시퀀스를 걸러내지 않기 때문에, 공격자는 미리보기 루트를 벗어나 서버의 다른 파일을 읽을 수 있습니다. 무인증·원격으로 성립하는 임의 파일 읽기(arbitrary file disclosure)입니다.
- CVSS 3.1: CNA 레코드 기준 9.8 (Critical), 벡터
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. ⚠️미확인(팩트체크 대상, 중요) — 모든 기술 자료가 이 결함을 읽기 전용 파일 노출로 서술합니다. 순수 파일 노출 취약점은 통상 무결성·가용성 영향이 없어C:H/I:N/A:N= 7.5로 매겨집니다.I:H·A:H성분은 서술된 동작으로 뒷받침되지 않아 과대 산정으로 보입니다(우리 추론). 팩트체커가 벡터를 직접 재계산해야 합니다. - CWE: CWE-22(경로 탐색, Improper Limitation of a Pathname to a Restricted Directory).
- 인증 요구: 없음(unauthenticated), 원격. 해당 컨트롤러에 인가 어노테이션(
@AuthCheck류)이 없어 무인증으로 도달 가능하다고 리서치 재료가 원본 소스 대조로 보고했습니다. ⚠️미확인 — 우리는 fetch로 직접 확증하지 못했으므로 팩트체크 대상입니다. - 영향 제품/버전: Yu AI Code Mother v4.3(CVE 설명 기준). 구조화 레코드의 벤더·버전 필드는
n/a로 표기돼 있습니다. ⚠️미확인 — 이 저장소에는 릴리스 태그가 없고 버전 번호가 튜토리얼 에피소드를 따라가는 것으로 보여, “v4.3”을 특정 커밋에 매핑하는 근거는 확인되지 않았습니다. - 수정 버전: 없음(발행 시점 미패치). 취약 파일에 대한 패치 커밋이 확인되지 않았고, 해당 코드가 최신 커밋에도 그대로 남아 있다고 리서치 재료가 보고했습니다.
- 연구자: fangtang7 (PoC advisory 공개).
한 줄 요약: 사용자가 준 경로를 “정규화 없이 이어 붙인다”는 한 줄이, 인증도 없는 파일 서버를 통째로 열어젖혔습니다.
기술 배경 — 경로 탐색과 “미리보기 루트”의 함정
경로 탐색(path traversal)은 웹 애플리케이션이 사용자가 준 파일 경로를 검증 없이 파일시스템 접근에 쓸 때 생깁니다. 서버가 기준디렉토리 + 사용자입력으로 실제 파일 경로를 만든다면, 사용자가 입력에 ../를 넣어 기준 디렉토리 위로 거슬러 올라갈 수 있습니다. 기준/사용자입력이 기준/../../etc/passwd 같은 형태로 풀리면, 의도한 폴더를 벗어나 서버의 임의 파일에 닿습니다. 이 부류(CWE-22)는 웹 보안에서 가장 오래된 교과서적 결함 중 하나입니다.
방어의 핵심은 경로를 실제 파일시스템 접근에 쓰기 전에 정규화(canonicalize)하고, 그 결과가 허용된 기준 디렉토리 안에 있는지 확인하는 것입니다. 정규화는 ../·심볼릭 링크·인코딩 변형을 실제 경로로 풀어주고, 경계 검사는 최종 경로가 루트를 벗어났는지 판정합니다. 이 두 단계 중 하나라도 빠지면 탐색이 성립합니다.
AI 코드 생성 플랫폼은 이 함정에 특히 노출되기 쉽습니다. “생성된 코드를 미리보기 폴더에 저장하고, 그 폴더를 정적으로 서빙한다”는 흔한 패턴에서, 미리보기 URL의 경로 부분이 곧바로 파일시스템 경로가 되기 때문입니다. 서빙 로직이 경로 정규화를 생략하면 미리보기 루트가 그대로 임의 파일 읽기 창구가 됩니다.
CVE 분석 요약 — 어느 코드가 원인인가
리서치 재료가 업스트림 오픈소스를 대조해 특정한 취약 지점은 다음과 같습니다. ⚠️미확인 — 우리는 fetch로 직접 확증하지 못했으므로, 아래 파일 경로·메서드·SHA·라인번호는 모두 팩트체크 대상입니다.
- 파일:
src/main/java/com/yupi/yuaicodemother/controller/StaticResourceController.java - 메서드:
serveStaticResource(HttpServletRequest request) - 엔드포인트:
GET /api/static/{deployKey}/** - 고정 커밋 SHA(취약 상태 = 현재 상태):
893918c808ce7828cd4b9372967e064ed119bbaa⚠️미확인 — 이 SHA와 아래 라인번호(약 52행 부근)는 리서치 재료가 준 근사치이며, 실제 라인 존재·바이트 일치는 팩트체커가raw.githubusercontent.com원문으로 대조해야 합니다.
취약의 뿌리는 서버가 파일 경로를 만드는 방식입니다. 미리보기 루트 디렉토리 뒤에 사용자가 통제하는 deployKey와 요청 경로(resourcePath)를 정규화·경계 검사 없이 문자열로 이어 붙입니다. 아래는 그 판단을 개념적으로 재구성한 것입니다.
// 개념용 단순화, 실제 페이로드/원본 코드 아님
// 취약 판단: 사용자 통제 경로를 정규화 없이 기준 디렉토리에 이어 붙임
String filePath = PREVIEW_ROOT_DIR + "/" + deployKey + resourcePath;
// PREVIEW_ROOT_DIR = 미리보기 루트, deployKey·resourcePath = 요청에서 옴
// canonicalize() 도, "결과가 PREVIEW_ROOT_DIR 안인가" 경계 검사도 없음
File file = new File(filePath); // → 루트 밖 파일에도 그대로 도달
여기서 두 가지가 동시에 빠져 있습니다. 첫째, 경로 정규화가 없어 resourcePath의 ../가 그대로 살아 상위 디렉토리로 거슬러 올라갑니다. 둘째, 최종 경로가 미리보기 루트 안에 있는지 확인하는 경계 검사가 없어 루트를 벗어난 접근을 막지 못합니다. 여기에 인가 어노테이션 부재(⚠️미확인)가 겹치면서, 무인증 공격자가 이 엔드포인트에 직접 요청을 던져 서버 파일을 읽을 수 있게 됩니다.
공격 시나리오 · 영향도 + 대응방안
공격 시나리오 (단계 압축, 완성형 페이로드 없음):
- 공격자가 인터넷 또는 같은 네트워크에서 도달 가능한 인스턴스의 정적 리소스 엔드포인트를 찾습니다. 인증은 필요 없습니다.
- 미리보기 경로 자리에 상위 이동 시퀀스를 실어, 서버가 만드는 최종 파일 경로가 미리보기 루트 바깥을 가리키게 유도합니다.
- 응답으로 미리보기 루트 밖 파일(예: 다른 사용자의 생성 코드, 설정·프로퍼티 파일)의 내용을 돌려받습니다.
영향도: 확인된 동작은 무인증 임의 파일 읽기입니다 — 파일 쓰기나 원격 코드 실행이 아니라 노출입니다. 그럼에도 파급은 작지 않습니다. 다른 사용자가 생성한 코드, 애플리케이션 설정 파일, 자격증명이 담긴 프로퍼티 등이 읽히면 2차 침해의 발판이 됩니다. 다만 실제 탐색 깊이는 배포 환경에 따라 다릅니다(⚠️미확인). PoC advisory는 내장 Tomcat이 일정 단계 이상의 ../를 정규화·거부할 수 있다고 언급했습니다. 즉 “임의 깊이로 자명하게 악용된다”는 단정은 과합니다 — 내장 Tomcat이냐 Nginx 리버스 프록시냐, URL 인코딩된 탐색을 쓰느냐에 따라 실제 도달 범위가 달라집니다. 실제 악용 관측 여부도 이 글의 리서치 범위에서 확인되지 않았습니다(⚠️미확인).
대응방안:
발행 시점 기준 벤더 패치가 확인되지 않았으므로, 대응은 근본 수정을 유도하면서 노출을 줄이는 보상적 통제를 병행합니다.
- 근본: 정적 리소스 서빙 로직에서 경로를 정규화한 뒤 경계 검사를 강제합니다. 최종 실제 경로(canonical path)를 구해 그 경로가 미리보기 루트로 시작하는지 확인하고, 아니면 거부합니다. 프레임워크가 제공하는 안전한 리소스 리졸버를 쓰고 직접 문자열 이어 붙이기를 피하는 것이 정석입니다. 오픈소스이므로 이 결함을 인지한 운영자는 자체 빌드에 이 검사를 넣거나 상류에 패치를 제안할 수 있습니다.
- 차선(패치 전 노출 최소화):
- 인스턴스를 인터넷에 직접 노출하지 않고, 신뢰된 네트워크·인증 프록시 뒤에 둡니다.
- 리버스 프록시(Nginx 등)나 WAF에서 정적 리소스 경로로 들어오는 요청의 상위 이동 시퀀스(
../, 인코딩 변형 포함)를 차단합니다. - 미리보기 서빙 프로세스의 파일시스템 권한을 미리보기 루트로 최소화해, 탐색이 성립하더라도 읽히는 범위를 줄입니다.
- 탐지 관점: 정적 리소스 엔드포인트로 들어오는 요청 중 경로에 상위 이동 시퀀스나 인코딩된 변형이 섞인 것을 로그에서 회귀 검색합니다. 미리보기 루트 밖 파일(설정·프로퍼티 등)에 대한 접근 시도가 관측되면 우선 조사 대상입니다.
결론
정적 파일을 서빙하는 코드는 “그냥 파일을 돌려주는 단순한 일”처럼 보이지만, 그 파일 경로를 누가 정하느냐가 전부입니다. 사용자가 정한 경로를 정규화 없이 믿는 순간, 정적 서버는 임의 파일 읽기 도구가 됩니다.
이 부류의 취약점이 반복되는 이유는 분명합니다. “기준 디렉토리 + 사용자 입력”으로 파일 경로를 만드는 패턴은 어디에나 있고, 정규화와 경계 검사라는 두 방어선은 빠뜨리기 쉬우면서 빠뜨려도 정상 동작은 멀쩡해 보이기 때문입니다. AI 코드 생성 플랫폼처럼 “생성물을 폴더에 쌓고 그 폴더를 서빙하는” 새 아키텍처에서는 미리보기 URL이 곧 파일 경로가 되어 이 오래된 함정이 다시 살아납니다. 여기에 무인증 접근이 겹치면 진입 장벽이 사라집니다. 이 한 틈은 언젠가 패치로 닫히겠지만, “사용자가 준 경로를 파일시스템에 쓰기 전에 정규화하고 경계를 확인하라”는 규칙은 다른 언어·다른 프레임워크에서 또 시험대에 오릅니다. 그래서 우리는 도구가 아니라 방법을 남깁니다.
References / 참고자료
- MITRE CVE Services(CVE Awg API), “CVE-2026-75337” — 이 글이 재구성한 1차 정본(CNA 레코드: 취약점 설명·affected·CWE·CVSS 벡터). https://cveawg.mitre.org/api/cve/CVE-2026-75337
- fangtang7, “YU_AI_4.3_TRAVERSAL_POC” — 취약점을 공개한 연구자의 PoC/advisory(읽기 전용 파일 노출·내장 Tomcat 정규화 관련 관찰). https://github.com/fangtang7/CVE/blob/main/yu-ai/YU_AI_4.3_TRAVERSAL_POC.md
- liyupi,
yu-ai-code-mother— 업스트림 오픈소스 저장소(제품 성격·취약 파일 위치의 소스). https://github.com/liyupi/yu-ai-code-mother - 취약 소스(고정 SHA raw, ⚠️미확인) —
StaticResourceController.java취약 상태 원문 대조용. https://raw.githubusercontent.com/liyupi/yu-ai-code-mother/893918c808ce7828cd4b9372967e064ed119bbaa/src/main/java/com/yupi/yuaicodemother/controller/StaticResourceController.java - NVD, “CVE-2026-75337” — 공식 취약점 레코드(발행 초기라 렌더 지연 가능, 팩트체크 재확인 대상). https://nvd.nist.gov/vuln/detail/CVE-2026-75337
이 글은 위 원 자료를 우리 관점에서 다시 쓰고 논평을 더한 것입니다. 특정 문장·코드를 그대로 옮기지 않았으며, 자세한 재현 절차는 원문을 참고하세요. ⚠️미확인 표시가 붙은 사실 주장(특히 CVSS 9.8 과대산정 의심·v4.3 커밋 매핑·인용 파일/라인/SHA·인가 어노테이션 부재)은 발행 전 독립 팩트체크로 1차출처 대조가 끝나야 확정됩니다.