Client Side Template Injection은 이용자의 입력 값이 client side template 프레임워크에 의해 템플릿으로 해석되어 렌더링될 때 발생된다.

 

 

 

Vue

 

Vue 혹은 Vue.js라고 불리는 프론트엔드 프레임워크는 2014년 출시된 프레임워크이며, 이용자 인터페이스나 Single Page Application을 빌드할 때 사용된다.

 

<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 템플릿 부분이다. 해당 템플릿 내에서 문자열을 표시하거나, 자바스크립트 표현식을 실행할 수 있다. 

만약 여기 템플릿 내부에 공격자의 입력이 삽입돼, Template Injection 취약점이 발생한다면, XSS 공격으로 이어질 수 있다.

 

 

<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>

 

위 코드는 htmlspecialchars() 함수를 사용하여 $_GET['msg']를 출력하므로, 기본적으로 XSS 공격에는 안전하다.

 

하지만 Template Injection 의 경우에는 상황이 조금 다르다.

Vue.js를 포함한 JavaScript 기반 프레임워크에서는 템플릿을 파싱하고, 실행 시점에 동적으로 내용을 갱신하는 기능이 있기 때문에, 사용자가 제공한 입력이 Vue 템플릿으로 해석되어 Template Injection 이 발생할 수 있다.

 


 

Template Injection이 발생하는지 확인하는 간단한 방법은 템플릿을 이용해 산술 연산을 수행해보는 것이다.

{{1+1}} 과 같은 산술 연산 형태의 템플릿을 입력했을 때, 연산이 실행된 형태인 2가 출력된다면 Template Injection이 발생하는 것으로 확인할 수 있다.

 

 

Template Injection이 발생할 때, 이를 이용해 임의의 자바스크립트 코드를 실행하는 방법으로 생성자(constructor)를 사용하는 방법이 있다. Vue 템플릿 컨텍스트 내에서 생성자에 접근하여 악성 코드를 생성하고 이를 호출하여 XSS 공격을 수행할 수 있다.

Vue 템플릿 컨텍스트에서 생성자에 접근하는 대표적인 방법을 {{_Vue.h.constructor}} 를 사용하는 것이다.

이를 이용한 익스플로잇 코드는 다음과 같다.

{{_Vue.h.constructor("alert(1)")()}}     →  alert(1) 실행

 

 

 

 

 

AngularJS

AngularJS는 타입스크립트 기반의 오픈소스 프레임워크이며 CLI 도구에서 다양한 기능을 제공하기 때문에 개발을 편리하게 해주는 프레임워크 중 하나다.

 

<!doctype html>
<html ng-app>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.3/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 템플릿 부분이며, 해당 템플릿 내에서 문자열을 표시하거나, 자바스크립트 표현식을 실행할 수 있다. 만약 여기서 템플릿 내부에 공격자의 입력이 들어가 Template Injection 취약점이 발생한다면, XSS 공격으로 이어질 수 있다.

 

 

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

 

htmlspecialchars 함수를 통해 msg 파라미터 출력하기 때문에 XSS 공격은 방지할 수 있지만, 출력되는 값이 AngularJS의 템플릿으로 사용될 수 있기 때문에 Template Injection이 발생한다.

 


 

{{1+1}} 과 같은 산술 연산 형태의 템플릿을 입력했을 때, 연산이 실행된 형태인 2가 출력된다면 Template Injection이 발생하는 것으로 확인할 수 있다.

 

Template Injection이 발생할 때, 이를 이용해 임의의 자바스크립트 코드를 실행하는 방법으로 생성자(constructor)를 사용하는 방법이 있다.  AngularJS 템플릿에서 생성자에 접근하기 위해서는 {{ constructor.constructor }}로 접근할 수 있다.

이를 이용하여 임의 코드에 해당하는 함수를 생성하고, 호출하여 공격할 수 있다

{{ constructor.constructor("alert(1)")() }}      →  alert(1) 실행

 

 

 

 

 

+ Recent posts