버그바운티(Bug Bounty) Write-up / DOM Based XSS ($500)
Security/BugBounty Study

버그바운티(Bug Bounty) Write-up / DOM Based XSS ($500)

https://hackerone.com/reports/474656

 

HackerOne disclosed on HackerOne: Cross-site Scripting (XSS) on...

Dear HackerOne team, **Summary:** I found DOM XSS at endpoint `https://www.hackerone.com/careers`, but can not bypass CSP. It's work on IE and Edge. ### Steps To Reproduce - JS file is "Masonry js file", vulnerability code: ```javascript //Checking for pot

hackerone.com


DOM Based XSS - $500

오늘도 역시 DOM Based XSS 에 관한 내용입니다. 이 건도역시 500달러를 바운티 받았습니다. 이 취약점은 조금 발생하기 힘든 조건이 있었지만 그래도 500달러를 바운티 했네요. 그냥 어떤조건이든 취약점이 있다면 바운티를 해주는것 같습니다.

이 DOM  Based XSS는 https://www.hackerone.com/careers 에서 발생했으며, 작성자는 해당 페이지 js에서 취약점을 발견해 제보했는데요. 문제는 CSP 우회는 하지못해서 IE와 Edge 브라우저에서만 취약점이 발생한다고 합니다. 

CSP(Content Security Policy) 란 콘텐츠 보안 정책으로 HTTP 헤더에 Content-Security-Policy: policy 이런식으로 추가를 하여 CSP를 사용할 수 있습니다. 단 브라우저에서 CSP 헤더를 지원해야만 합니다. 이 콘텐츠 보안 정책으로 XSS 공격을 어느정도 방어 할 수 있습니다. 보통 XSS 는 서버로부터 받은 데이터에 대한 브라우저의 신뢰성을 악용하면서 발생합니다. 브라우저가 그냥 서버로부터 받은 데이터는 정상이라고 생각하고 실행해버리기 때문에 발생한다는 뜻이죠. 이 CSP는 브라우저가 화이트리스트 기반으로 검증된 도메인에서 받은 스크립트만 실행 하도록 하기 때문에 XSS 공격에 대해 어느정도 방어가 가능합니다.

이제 작성자가 취약점을 발견한 코드를 보겠습니다.

Masonry.js

먼저 pageUrl 이라는 변수안에 현재 페이지의 URI를 받아옵니다. 그다음 trackingPrerfix 라는 변수에는 ?lever- 라는 단어가 들어가게 되는데요. 이 단어를 이용하여 URI를 잘라서 URI 내부에 있는 파라미터 값을 파싱합니다. 여기서 문제가 발생합니다. 파싱한 값에 대한 아무런 검증이 없다는 점이죠.

Masonry.js

그다음 그 파싱한 값을 jQuery 를 사용하여 #job-container의 id를 가진 부분 내 .job-list 라는 class 명을 가진부분에 append 함수를 사용하여 DOM을 제어합니다.

현재 파싱되어서 삽입되는 내용은 link 라는 변수안에 저장되어 있고 이 변수에 대한 값은 중간쯤에 보시면 '<a class="job-title" href="' + link + '"">' 라는 부분에 들어갑니다.

https://www.hackerone.com/careers?lever-#aaa"><script src="https://app-sj17.marketo.com/index.php/form/getForm?callback=alert"></script>

그래서 공격자는 #aaa"><script src="https://app-sj17 .... callback=alert"></script> 이런 공격코드를 작성하여, 앞의 href 폼을 닫아주고, alert창을 띄울수 있도록 만들었습니다.

alert

그리고 이렇게 XSS가 성공했네요.


이제 보고서의 내용에 대한 건 접어두고, 여기서 jQuery를 사용하기위해서 jQuery  정의 문자인 $(달러) 를 사용하지않고 jQuery라는 문자를 사용한 것에 대해서 의문점이 생겨서 찾아보았습니다.

Masonry.js

 

jQuery를 사용하기 위해서 굳이 $를 사용하지 않아도 된다고 하는데요. 사실은 안정적인 측면에서 $(달러) 보다 jQuery 정의자를 사용하는게 더 좋다고 합니다. 왜냐하면 다른 라이브러리에서 '$' 문자를 사용한다면, 충돌이 일어날 수 있기 때문입니다. 그래서 jQuery라는 정의어를 사용하기 위해서 jQuery.noConflict(); 라는 문장을 넣어주게되면, 사용이 가능해 집니다.

 

1
2
3
4
5
6
7
8
9
<script>
 
jQuery.noConflict();
 
jQuery.(document).ready(function(){
    
});
 
</script>
cs

이렇게 $대신 사용할 수 있게됩니다.