Oh My Posh Path Template Injection을 통한 Arbitrary Command Execution 분석 (CVE-2026-73505)

lshdf·2026년 7월 31일

cve

목록 보기
2/3
post-thumbnail
Severity: High
Reporter: ihopenre-eng
Published: July 2026

Introduction

최근 제가 Oh My Posh 프로젝트에서 보고한 취약점이 GitHub Security Advisory(CVE-2026-73505)로 공개되었습니다.

이번 취약점은 단순한 템플릿 처리 문제가 아니라, 사용자가 현재 위치한 디렉터리 이름을 다시 Go text/template 엔진으로 렌더링하는 과정에서 발생했습니다.

디렉터리 이름에 Go Template 표현식을 포함하면, 프롬프트가 렌더링되는 시점에 해당 표현식이 실행됩니다. 특히 템플릿 함수(cmd)를 통해 운영체제 명령을 실행할 수 있어 현재 사용자 권한으로 임의 명령 실행(Arbitrary Command Execution) 이 가능했습니다.

이번 글에서는 취약점을 분석하면서 어떤 코드가 원인이 되었는지, 실제로 어떻게 명령 실행으로 이어졌는지 살펴보겠습니다.

Oh My Posh는 어떻게 Path를 표시할까?

여기서는 먼저 Path Segment가 어떻게 생성되는지 설명합니다.

Prompt 렌더링 구조도

처음 의심했던 부분


처음에는 이 코드가 단순히 설정 파일에 포함된 템플릿만 처리하는 것으로 생각했습니다.

하지만 pt.Path가 어디에서 만들어지는지 계속 따라가 보니 조금 다른 모습을 확인할 수 있었습니다.

pt.Path는 어디에서 오는가?


folder name이

fmt.Sprintf(folderFormat, element)

로 들어가는 부분.

element는 현재 작업 디렉터리의 실제 폴더 이름입니다.

즉,

hello

도 들어가고

{{ cmd `whoami` }}

같은 문자열도 그대로 들어갑니다.

문제는 "두 번째 Template Rendering"

여기가 핵심입니다.

여기서

이미 사용자 입력이 포함된 문자열을 다시 Template Engine으로 해석하고 있었습니다.

cmd 함수는 무엇을 할까?

템플릿 엔진에는 여러 함수가 등록되어 있는데,

그중 cmd()는 운영체제 명령을 실행하는 함수입니다.

즉,

{{ cmd "whoami" }}

가 Template 안에서 실제 명령을 실행합니다.

왜 이것이 RCE가 되는가?


이 그림 하나 있으면 이해가 엄청 쉬워집니다.

PoC

프롬프트를 렌더링하는 순간

whoami

명령이 실행되고

출력이 Prompt에 그대로 반영됩니다.

Windows 검증

powershell


실행 후

pwn3d

파일 생성.

영향

여기서 실제 공격 시나리오.

Git Clone
ZIP 압축
USB
Network Share

사용자가

cd

하는 순간

Prompt Rendering

↓

Command Execution

패치

패치 Diff.

여기서

Template.Render 제거

또는

Escape

되는 부분.

마무리

이 취약점은 Go Template 자체의 문제가 아니라 신뢰할 수 없는 데이터를 Template로 다시 해석(Double Evaluation) 한 것이 원인이었습니다.

템플릿 엔진는 설정 파일처럼 신뢰할 수 있는 입력을 처리할 때는 매우 유용하지만, 사용자나 파일시스템에서 가져온 문자열을 그대로 다시 렌더링하면 의도하지 않은 코드 실행으로 이어질 수 있습니다.

이번 사례는 "데이터와 템플릿을 명확히 구분해야 한다"는 기본 원칙이 얼마나 중요한지를 보여주는 사례라고 생각합니다.

profile
CVE-2026-73842 CVE-2026-73841 CVE-2026-73505 CVE-2026-73840 CVE-2026-73506 GHSA-hj4x-hm4v-7wpw GHSA-gc47-hwcc-8qp4 GHSA-6rg8-xpvg-m49w

0개의 댓글