← 목록으로

SSTI (Server-Side Template Injection): 원리와 탐지

[Web] Web · 작성: 2026-07-20 03:10:34 · 수정: 2026-07-20 03:11:15 · 조회 10

XSS가 "브라우저가 해석하는 HTML/JS"에 사용자 입력이 섞여드는 문제라면, SSTI는 "서버가 해석하는 템플릿 문법"에 사용자 입력이 섞여드는 문제다. 이 블로그도 EJS로 서버 렌더링을 하는데, 만약 사용자 입력을 템플릿 문자열 자체에 그대로 이어 붙이는 코드가 있었다면 같은 문제가 생겼을 것이다 — 실제로는 항상 값을 변수로 넘겨서 렌더링하기 때문에 안전하고, 이 차이가 SSTI의 핵심이다.

취약한 패턴 vs 안전한 패턴

// 취약: 사용자 입력을 템플릿 "문자열" 자체에 이어붙여서 컴파일
const template = "안녕하세요 " + req.query.name;
res.send(ejs.render(template));

// 안전: 템플릿은 고정, 사용자 입력은 "값"으로만 전달
res.render('greet', { name: req.query.name });

첫 번째 방식은 req.query.name에 EJS 문법 자체(예: 셸 명령을 실행하는 구문)를 넣으면 서버에서 그대로 코드로 실행된다.

템플릿 엔진마다 다른 페이로드

SSTI는 어떤 템플릿 엔진을 쓰느냐에 따라 문법이 다 다르다.

탐지

XSS 페이로드로는 안 터지는데 {{7*7}}처럼 엔진별 산술식 문법을 넣었을 때 결과값(49)이 그대로 반영되면 SSTI 후보다. 어떤 문법에 반응하는지로 엔진을 특정하고, 그 엔진 전용 페이로드로 전환한다.

방어

Web 카테고리의 글 (8/11)

  1. SQL Injection: 원리, 탐지, 방어
  2. XSS (Cross-Site Scripting): Stored / Reflected / DOM 차이와 방어
  3. CSRF (Cross-Site Request Forgery): 원리와 방어
  4. IDOR / BOLA: 권한 검증이 빠졌을 때
  5. SSRF (Server-Side Request Forgery): 서버가 대신 요청하게 만들기
  6. 파일 업로드 취약점: 웹쉘로 이어지는 경로
  7. 안전하지 않은 역직렬화 (Insecure Deserialization)
  8. SSTI (Server-Side Template Injection): 원리와 탐지
  9. OS Command Injection: 원리와 필터 우회
  10. JWT 취약점: alg=none부터 알고리즘 컨퓨전까지
  11. Race Condition (TOCTOU) 취약점
← 안전하지 않은 역직렬화 (Insecure Deserialization) OS Command Injection: 원리와 필터 우회 →