드림핵 - WHA(Client Side)

Client Side Template Injection

김가윤 2023. 4. 18. 13:43

1. 서론

 

Client Side Template Injection은

이용자의 입력값이

client side template framework에 의해

템플릿으로 해석되어

렌더링될 때 발생한다.

 

개발의 편의성을 높여주는 프레임워크지만

잘못된 방식으로 사용할 경우,

XSS 취약점까지 연계하는 것이 가능하다.


2. Client Side Template Injection

 

2-1 Vue - Vue.js

 

오픈소스 자바스크립트 프레임워크로

이용자 인터페이스나

Single Page Application을 빌드할 때 사용된다.

 

Figure 1. Vue 예제

<script src="https://unpkg.com/vue@3"></script>
<div id="app">{{ message }}</div>
<script>
  Vue.createApp({
    data() {
      return {
        message: 'Hello Vue!'
      }
    }
  }).mount('#app')
</script>

 

{{ }}로 감싸진 부분이

Vue 템플릿 부분이다.

 

해당 템플릿 내에서

문자열을 표시하거나

자바스크립트 표현식을 실행할 수 있다.

 

Figure 2. 취약한 Vue 예제

<script src="https://unpkg.com/vue@3"></script>
<div id="app">
	<?php echo htmlspecialchars($_GET['msg']); ?>
</div>
<script>
  Vue.createApp({
    data() {
      return {
        message: 'Hello Vue!'
      }
    }
  }).mount('#app')
</script>

 

입력받은 GET 메소드의 msg 파라미터를

그대로 출력하지만,

htmlspecialchars 함수를 통해

꺽쇠 문자가 모두 인코딩되기 때문에

일반적인 XSS 공격은 불가능하다.

 

하지만 출력되는 값이

Vue의 템플릿으로 사용될 수 있기 때문에

Template Injection이 발생한다.

 

2-2 Vue Template Injection

 

Vue Template Injection

발생하는지 확인하는 간단한 방법은

템플릿을 이용해 산술 연산을 수행해 보는 것이다.

 

{{1+1}} 템플릿을 입력했을 때 2가 출력된다면

Template Injection이 발생하는 것으로 확인할 수 있다.

 

Template Injection이 발생할 때

이를 임의 자바스크립트 코드 실행으로 연계하는 방법으로

보통 생성자 (constructor)를 이용한다.

 

Vue 템플릿 컨텍스트에서 대표적으로

{{_Vue.h.constructor}}를 이용해 접근할 수 있다.

 

Figure 4. Vue Template Injection 공격

{{_Vue.h.constructor("alert(1)")()}}


2-3 Angular JS

 

Angular JS

타입스크립트 기반의 오픈소스 프레임워크이며

CLI 도구에서 다양한 기능을 제공하기 때문에

개발을 편리하게 해주는 프레임워크 중 하나이다.

 

Figure 5. Angular JS 예제

<!doctype html>
<html ng-app>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
  </head>
  <body>
    <div>
      <label>Name:</label>
      <input type="text" ng-model="yourName" placeholder="Enter a name here">
      <hr>
      <h1>Hello {{yourName}}!</h1>
    </div>
  </body>
</html>

 

Vue와 마찬가지로

{{ }}로 감싸진 부분이 AngularJS 템플릿 부분이며,

 

해당 템플릿 내에서

문자열을 표시하거나,

자바스크립트 표현식을 실행할 수 있다.

 

Figure 6. Angular JS 취약한 예제

<!doctype html>
<html ng-app>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
  </head>
  <body>
      <?php echo htmlspecialchars($_GET['msg']); ?>
  </body>
</html>

 

2-4 Angular Template Injection

 

Vue와 마찬가지로

산술 연산이 실행된 결과가 출력되는지의 여부로

Template Injection을 탐지할 수 있다.

 

AngularJS 템플릿에서

생성자에 접근하기 위해서는

{{ constructor.constructor }}로 접근할 수 있다.

 

Figure 7. Angular Template Injection 공격

{ constructor.constructor("alert(1)")() }}


3. 정리

 

Client Side Template Injection은

꺽쇠와 같은 특수문자가 필터링 되었더라도

XSS로 연계할 수 있어 파급력이 높은 취약점이다.

 

프론트엔드 프레임워크를 이용할 때에는

반드시 production mode로 코드를 빌드하여 사용하고,

이용자의 입력이 템플릿으로 인식되지 않도록 유의하여야 한다.