SSTI(Server Side Template Injection)
목차
1. 정의
SSTI(Server Side Template Injection)란 서버에서 HTML을 생성할 때 사용하는 템플릿 엔진(Jinja2, Twig, FreeMarker 등)에 공격자가 의도적으로 템플릿 문법을 주입해 서버 측에서 템플릿이 해석/실행되게 만드는 취약점이다.
단순한 화면 변조를 넘어서 상황에 따라 민감정보 노출, 내부 로직 우회, 원격 코드 실행(RCE)까지 이어질 수 있다.
1.1. 웹 템플릿 엔진
템플릿 엔진(Template engine)은 템플릿 양식과 특정 데이터 모델에 따른 입력 자료를 합성하여 결과 문서를 출력하는 소프트웨어 또는 소프트웨어 컴포넌트를 말한다. 특히 웹 템플릿 엔진은 웹 문서가 출력되는 템플릿 엔진을 말한다.
HTML을 문자열로 직접 이어 붙이는 대신, 템플릿과 데이터를 분리해서 유지보수, 재사용, 가독성을 크게 높일 수 있다.
2. 동작 원리
서버 사이드 템플릿의 렌더링은 아래와 같은 흐름으로 동작한다.

출처: Tistory: /SSTI-공격-이론-및-실습-Server-Side-Template-Injection
- 템플릿과 컨텍스트(변수 값들)를 합쳐서
- 템플릿 엔진이 코드(
{{...}},{%...%}등)를 해석해 - 최종 HTML을 만들어서 응답한다.
SSTI는 공격자의 입력이 컨텍스트 값이 아니라, 템플릿 코드로 들어가면서 발생한다.
3. 탐지 방법론: Detect → Identify → Exploit

3.1. Detect(탐지)
SSTI는 명시적으로 찾지 않으면 쉽게 보이지 않기 때문에 템플릿 문법에서 흔한 특수문자 시퀀스(${{<%['"}}%>\)를 넣어 에러 또는 이상징후가 나는지로 접근한다.
컨텍스트를 구분해서 재검증한다.
- Plaintext Context: 사용자 입력이 결과 HTML로 그냥 출력되는 자리에 들어갈 경우이다.
- 산술 연산 같은 무해한 표현식을 넣은 결과가 서버에서 계산되어서 바뀌는 지 본다.
- 예:
7*7→49로 출력 - 계산 결과가 출력되면 서버에서 템플릿이 평가된다는 PoC가 된다.
- Code Context: 사용자 입력이 템플릿 표현식 내부(예:
{{ ... }}안의 변수명 자리 등)에 들어가는 경우이다.- HTML 태그 등을 넣어 직접 XSS가 되는지 확인한다. 안 될 경우 빈 출력, 인코딩, 에러로 끝나는 경우가 많다.
- 템플릿 구문을 닫고(break out) 뒤에 임의 HTML을 붙여, 문장 밖으로 탈출되면서 임의의 출력이 가능한지를 PoC로 본다.
3.2. Identify(식별)
탐지 신호 발견 후 템플릿 엔진을 식별한다.
3.2.1. 에러 메시지로 식별한다
일부러 잘못된 문법을 넣어 에러를 유도하면, 에러 메시지에 엔진 이름, 버전이 그대로 드러나는 경우가 있다.
예: <%=foobar%>
결과 - ERB Engine:
(erb):1:in `<main>': undefined local variable or method `foobar' for main:Object (NameError)
from /usr/lib/ruby/2.5.0/erb.rb:876:in `eval'
from /usr/lib/ruby/2.5.0/erb.rb:876:in `result'
from -e:4:in `<main>'
3.2.2. probing payload로 소거한다
에러가 안 나오면, 엔진별로 문법이 비슷하다는 점을 이용해 수학 연산 probing 등을 여러 문법으로 넣고 평가되는지, 어떻게 평가되는지를 관찰해 후보를 좁혀간다.

3.2.3. 단일 결과로 단정하지 않는다
같은 payload가 둘 이상의 엔진에서 성공할 수 있으니, 한 번의 성공만 보고 결론을 내리지 않는다.
4. 보안 대책
기본적으로 Injection 보안 대책을 따른다. 데이터를 명령/쿼리와 분리해야 한다. 사용자가 템플릿을 수정/제출할 수 없게 하는 것이 제일 좋다.
- 템플릿과 데이터를 섞지 않는다.
- 사용자 입력을 문자열 포맷팅으로 템플릿과 합치지 말고, 항상 컨텍스트 변수로만 전달한다.
- 템플릿 컨텍스트에 위험한 객체를 넘기지 않는다.
- 템플릿에
os,sys, 설정 객체, DB connection, request 전체 객체 등 강한 권한과 광범위한 접근 객체를 넘기지 않도록 한다.
- 템플릿에
참고
- Tistory: [Web] 템플릿 엔진, JSP, Thymeleaf란? 서버 사이드 템플릿 엔진 vs 클라이언트 사이드 템플릿 엔진
- Tistory: SSTI-공격-이론-및-실습-Server-Side-Template-Injection
- Tistory: flask 기본적인 문법과 사용법1(라우팅, url변수, url 얻어오기, render_template, get,post통신)
- IGLOO: Thymeleaf 환경의 SSTI 공격사례 및 대응 방안: Template fragment와 CVE-2023-38286기반의 SSTI
- MointorApp: Server Side Template Injection
- GithubPages: Server-Side Template Injection(SSTI)
- StackHawk: Finding and Fixing SSTI Vulnerabilities in Flask (Python) With StackHawk
- Intigriti: SSTI: A complete guide to exploiting advanced server-side template injections
- PortSwigger: Server-side template injection
- OWASP: Testing for Server Side Template Injection
Comments