flawopen.com/SSTI/설명
서버 사이드 템플릿 인젝션이란?
서버 사이드 템플릿 인젝션은 신뢰할 수 없는 입력을 데이터가 아닌 템플릿 소스로 파싱하게 할 때 발생합니다. 영향은 엔진, 설정, 노출된 기능에 따라 표현식 평가부터 서버 코드 실행까지 달라집니다. 모든 SSTI가 코드 실행으로 이어지는 것은 아닙니다.
# Python / Jinja2 template = f"Hello {name}!" return render_template_string(template) # Input: {{ 7*7 }} renders as "49" # This confirms expression evaluation; # impact still depends on engine access. // Java / Freemarker String tpl = "Welcome " + userName; new Template("t", tpl, cfg) .process(model, out);
# The template is a fixed string the # developer wrote. The user value is # passed in as a variable. return render_template( "greeting.html", name=name ) # Or with a literal template string: return render_template_string( "Hello {{ name }}!", name=name ) // Java equivalent: template from file, // user value in the model map.
핵심적인 차이
템플릿 엔진에는 템플릿과 컨텍스트 데이터라는 두 입력이 있습니다. 템플릿은 프로그램이고 데이터는 프로그램이 읽는 값입니다. SSTI는 사용자 입력이 데이터에서 템플릿 소스로 넘어가게 허용하는 실수입니다.
이는 데이터를 쿼리 텍스트에 연결하는 SQL 인젝션과 같은 구조적 오류이며, 로그 메시지로 데이터가 표현식 평가기에 도달한 Log4Shell과도 유사합니다. 원칙은 같습니다. 프로그램을 고정하고 신뢰할 수 없는 값은 매개변수 채널로 전달하세요.
코드 실행이 가능한 영향 조건
엔진이 강력한 객체나 메서드를 템플릿에 노출하면 공격자가 애플리케이션의 민감한 기능에 접근할 수 있습니다. 코드 실행 여부는 엔진, 버전, 설정, 샌드박스와 데이터 모델에 따라 달라집니다. 정보 노출이나 리소스 고갈도 가능합니다. 사용자 제어 템플릿 소스를 활성 로직으로 취급하고 접근 객체와 렌더링 리소스를 제한하지 않은 채 샌드박스만 믿지 마세요.
탐지 방법
{{7*7}}
${7*7}
<%= 7*7 %>
#{7*7}
응답에 원문 대신 49가 나오면 입력이 템플릿 문법으로 평가된 것입니다. 권한이 있는 테스트 환경에서 짧은 산술 프로브로 평가 여부를 확인할 수 있습니다. 문법은 엔진마다 다르며 이것만으로 엔진을 확실히 식별할 수는 없습니다.
자주 묻는 질문
아닙니다. 클라이언트 템플릿 인젝션은 피해자 브라우저에서 실행되며 XSS 유형일 수 있습니다. SSTI는 서버의 애플리케이션 프로세스에서 평가됩니다. 영향은 엔진과 노출 기능에 따라 다르며 일부 설정에서 코드 실행이 가능하지만 모든 SSTI에서 자동 발생하지는 않습니다.
아닙니다. 자동 이스케이프는 렌더링되는 값을 처리하지만 값이 템플릿 문법으로 파싱되는 것을 막지는 않습니다. 출력의 XSS를 방어할 뿐 템플릿 소스 주입을 방지하지 않습니다.
사용자 제공 템플릿 소스를 실행 가능한 로직으로 보고 기본적으로 주 애플리케이션 컨텍스트에서 처리하지 마세요. 필요하다면 제한 템플릿용 엔진을 쓰고 최소한의 불활성 데이터만 노출하며 CPU, 메모리, 출력 크기와 시간을 제한하세요. 샌드박스만으로 완전한 경계가 되지는 않습니다.
참고 자료
- CWE-1336 — Improper Neutralization of Special Elements Used in a Template Engine
- PortSwigger Web Security Academy — server-side template injection
- OWASP Testing Guide — testing for SSTI
- Is Jinja2's render_template_string() safe?
- Are Freemarker and Velocity templates safe with user input?
- Jinja documentation — Sandbox security considerations