웹 애플리케이션 개발에서 템플릿 엔진은 동적인 콘텐츠 생성을 위한 필수적인 도구로 자리 잡았습니다. 템플릿 엔진은 데이터를 기반으로 HTML을 동적으로 생성하여 효율적이고 유지보수 가능한 코드를 작성하는 데 도움을 줍니다. 하지만, 사용자 입력을 제대로 검증하지 않을 경우 템플릿 엔진이 가진 기능이 보안 취약점으로 이어질 수 있습니다.
그중 대표적인 예가 바로 서버 측 템플릿 인젝션(Server-Side Template Injection, SSTI)입니다. SSTI 취약점은 공격자가 템플릿 엔진의 취약점을 악용해 서버에서 코드를 실행하거나 민감한 데이터를 노출시키는 심각한 보안 문제를 야기합니다. 특히, 잘못된 사용자 입력 처리로 인해 발생하는 SSTI는 공격자가 서버를 장악할 수 있는 길을 열어주기 때문에 더욱 위험합니다.
이번 글에서는 템플릿 엔진이 웹 애플리케이션에서 수행하는 기본적인 역할과 구조부터 SSTI 취약점의 동작 원리와 보안상의 위험성, 그리고 이를 탐지하고 예방할 수 있는 방법까지 소개해드리겠습니다.
👀 템플릿 엔진(Web Template Engine) 이란?
템플릿 엔진(Web Template Engine)은 웹 애플리케이션에서 데이터를 HTML에 결합하여 동적인 콘텐츠를 생성하는 도구입니다. 이를 통해 정적인 HTML 코드만으로는 구현하기 어려운 맞춤형 웹 페이지를 손쉽게 생성할 수 있습니다. 대표적인 템플릿 엔진으로는 Python의 Jinja2, JavaScript의 EJS, 그리고 PHP의 Blade 등이 있습니다. 이들은 데이터를 기반으로 HTML 구조를 동적으로 생성하며, 반복적인 작업을 줄이고 효율적인 개발 환경을 제공합니다.
템플릿 엔진의 기본 작동 방식은 간단합니다. 템플릿 파일은 HTML 코드와 함께 데이터가 삽입될 자리를 표현식으로 정의하고, 서버는 이 템플릿에 데이터를 삽입하여 완성된 HTML을 생성한 뒤 클라이언트에 반환합니다. 하지만 템플릿 엔진이 사용자 입력을 처리하는 방식에 따라 심각한 보안 취약점이 발생할 수 있습니다.
🔓 템플릿 엔진에서 발생할 수 있는 대표 보안 취약점 예시, 서버 측 템플릿 인젝션 (SSTI)
사용자 입력을 제대로 검증하지 않을 경우 템플릿 엔진이 가진 기능이 보안 취약점으로 이어질 수 있는 대표적인 예가 ‘서버 측 템플릿 인젝션(Server-Side Template Injection, SSTI)’ 입니다. 다음은 SSTI가 발생할 수 있는 간단한 코드 예시입니다.
|
from jinja2 import Template user_input =“{{ 7 * 7 }}” # 사용자 입력 template = Template(user_input) rendered = template.render() print(rendered) # 출력: 49 |
위 코드는 사용자가 입력한 값을 템플릿 엔진이 처리하여 결과를 생성합니다. 이 예시에서 user_input은 사용자 입력이라 가정합니다. 이는 단순한 문자열처럼 보이지만 템플릿 엔진은 7 * 7 를 계산하고, 49를 결과로 반환합니다. 원래라면 단순히 {{ 7 * 7 }}이라는 문자열이 출력되어야 하지만, 템플릿 엔진이 입력 값을 실행 가능한 코드로 인식하고 처리하면서 계산된 결과를 출력하게 됩니다.
문제는 이 기능이 악용될 경우 서버의 보안이 심각하게 위협받는다는 점입니다.
예를 들어, 공격자가 입력값으로 {{ __import__(‘os’).system(‘ls’) }}를 사용하면, 서버의 디렉토리 목록이 노출됩니다. 이는 시스템 명령어 실행을 통해 서버 내부를 탐색할 수 있는 방법을 제공합니다. 더 나아가, {{ __import__(‘os’).system(‘cat /etc/passwd’) }}와 같은 명령을 삽입하면 민감한 계정 정보를 추출할 수도 있습니다. 이는 CWE-1336에 명시된 내용으로, 서버 측 템플릿 인젝션을 악용한 입력 검증 부족에 의해 발생합니다.
🛡️ 서버 측 템플릿 인젝션(SSTI) 탐지 및 예방법
SSTI를 방지하려면 템플릿 엔진에 전달되는 html.escape()와 같은 내장 라이브러리를 사용해 사용자 입력을 철저히 검증하고, 허용된 값만 처리되도록 제한하는 것이 가장 중요합니다. 예를 들어, 입력값이 반드시 특정 형식이나 값에 부합해야 한다면, 이를 화이트리스트 방식으로 제한하여 예상치 못한 데이터가 템플릿에 삽입되지 않도록 해야 합니다.
또한, 템플릿 엔진의 고급 기능을 비활성화하는 것도 효과적인 방법입니다. 템플릿 엔진이 코드 실행이나 파일 시스템 접근과 같은 위험한 기능을 제공하는 경우, 이를 제한하거나 Jinja2의 sandbox 모드와 같은 보안 기능을 활용해야 합니다.
템플릿 엔진은 웹 애플리케이션에서 동적인 콘텐츠 생성을 효율적으로 처리할 수 있도록 돕는 도구입니다. 그러나 사용자 입력을 적절히 검증하지 않으면 SSTI과 같은 심각한 취약점이 발생할 수 있습니다. 공격자는 SSTI를 악용해 시스템 명령어를 실행하거나 민감한 데이터를 탈취하며, 심지어 서버를 완전히 장악할 수도 있습니다.
지금까지 템플릿 엔진의 기본 작동 방식과 SSTI의 위험성을 살펴보고, 실제 공격 시나리오를 통해 이 취약점이 얼마나 치명적인 결과를 초래할 수 있는지 알아보았습니다. 이를 방지하기 위해 사용자 입력을 철저히 검증하고, 템플릿 엔진의 보안 설정을 제한하며, HTML 이스케이프 처리를 포함한 방어 전략이 필요합니다.
특히, 이러한 취약점을 탐지하려면 Burp Suite와 같은 프록시 도구를 활용하여 수동으로 점검하거나, DAST(Dynamic Application Security Testing)와 같은 도구를 통해 자동화된 검사를 수행하는 것이 중요합니다. 수동 점검과 자동화 검사를 병행하면 다양한 취약점을 효과적으로 탐지하고 보안을 강화할 수 있습니다.
스패로우는 웹 애플리케이션 취약점 동적 분석 도구, Sparrow DAST를 공급하고 있습니다. Sparrow DAST는 대표 URL에 포함된 하위 경로를 자동으로 수집해 웹 취약점을 자동으로 검출하여 쉽고 간편합니다. 또한, 주요정보통신기반시설 취약점 분석 평가 기준 및 전자금융감독규정 등 다양한 컴플라이언스와 표준가이드를 준수하여 보안 취약점을 점검해 홈페이지의 안정성과 신뢰성을 확보할 수 있습니다. 뿐만 아니라 취약점 공격 과정을 이벤트 별로 재현하는 기능이 있어 웹 해킹 과정을 빠르게 파악할 수 있어요. Sparrow DAST를 링크를 통해 더 자세히 확인해보세요!
