맨위로가기

JSONP

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

JSONP는 웹 페이지가 다른 도메인의 서버에서 데이터를 가져올 수 있게 해주는 기술이다. 웹 브라우저의 동일 출처 정책으로 인해 일반적으로 불가능하지만, HTML `

더 읽어볼만한 페이지

  • JSON - JSON 웹 토큰
    JSON 웹 토큰(JWT)은 헤더, 페이로드, 서명으로 구성되어 정보를 안전하게 전송하는 개방형 표준으로, 사용자 인증 및 권한 부여에 주로 사용되지만 알고리즘 관련 취약점, 키 관리, 토큰 무효화 등의 문제점도 존재한다.
  • JSON - JSON-LD
    JSON-LD는 JSON 데이터를 RDF 모델로 표현하는 직렬화 방법으로, 컨텍스트를 활용해 JSON 속성을 온톨로지 개념에 연결하며 SEO, 의료 정보학, IoT 등 다양한 분야에서 활용되고 Schema.org, 구글 지식 그래프 등에서 중요한 역할을 한다.
  • Ajax - 구글 문서도구
    구글 문서도구는 구글에서 제공하는 웹 기반 워드 프로세서로, 문서 작성, 편집, 공유 기능을 제공하며, 다양한 문서 형식 지원, 실시간 공동 작업, 머신러닝 기반 기능을 제공하고, 구글 드라이브를 통해 문서 및 파일을 함께 이용할 수 있다.
  • Ajax - AngularJS
    AngularJS는 동적 웹 애플리케이션 개발을 용이하게 하기 위해 설계된 오픈 소스 자바스크립트 프레임워크로, MVC 패턴 적용, 의존성 주입, HTML 확장 디렉티브 제공, 양방향 데이터 바인딩 등의 특징을 가지며, 장기 지원은 종료되었지만 웹 개발에 중요한 영향을 미쳤다.
JSONP - [IT 관련 정보]에 관한 문서
파일 정보
JSONP 로고
JSONP 로고
MIME 형식application/json-p
파일 확장자.jsonp
장르데이터 교환
확장 형식JSON
JavaScript
웹사이트JSON-P 공식 웹사이트 (현재 링크 끊김, 보존된 링크 참조)
개요
JSONPJSON with Padding (JSONP)
설명JavaScript 프로그램에서 웹 브라우저의 CORS (Cross-Origin Resource Sharing) 정책을 우회하여 다른 도메인에서 데이터를 요청하는 데 사용되는 통신 프로토콜
개발 동기Bob Ippolito가 2005년 12월 5일에 제안

2. 동작 원리

웹 브라우저는 보안을 위해 동일 출처 정책을 따르므로, 웹 페이지는 일반적으로 자신의 도메인이 아닌 다른 도메인의 서버와 직접 통신할 수 없다. 그러나 HTML `<script>` 태그는 예외적으로 다른 도메인의 URL을 `src` 속성에 지정하여 해당 도메인의 데이터를 가져올 수 있다.

JSONP는 `<script>` 태그의 이러한 특성을 활용한다. 다른 도메인의 URL을 `<script>` 태그의 `src` 속성에 지정하고, URL에 데이터 요청 쿼리 문자열을 추가한다. 서버는 요청받은 JSON 데이터를 클라이언트가 미리 정의한 콜백 함수를 호출하는 형태로 감싸서 응답한다.

예를 들어, `parseResponse`라는 콜백 함수를 사용한다면, 다음과 같은 `<script>` 태그가 삽입된다.

```html



```

서버는 `callback` 파라미터로 전달된 `parseResponse` 함수 이름을 확인하고, JSON 데이터를 `parseResponse` 함수 호출로 감싸 응답한다.

```javascript

parseResponse({"Name":"Smith","Rank":7})

```

웹 브라우저는 이 응답을 유효한 JavaScript 코드로 인식하여 실행하고, `parseResponse` 함수가 호출되며 JSON 데이터가 인자로 전달된다. 이로써 동일 출처 정책을 우회하여 다른 도메인의 데이터를 안전하게 가져와 처리한다.[3]

2. 1. 기본 메커니즘

웹 브라우저에서 실행되는 JavaScript는 동일 출처 정책에 따라 XMLHttpRequest와 같은 직접적인 HTTP 통신을 이용해 외부 출처에서 데이터를 받아오는 것이 불가능하다. 하지만, HTML `<script>` 요소는 외부 출처로부터 조회된 내용을 실행하는 것이 허용된다.[3]

예를 들어, 외부 서비스 `http://server.example.com/Users/1234`에서 사람 Foo의 기록을 JSON 포맷으로 반환한다고 가정해 보자.

```json

{

"Name": "Foo",

"Id": 1234,

"Rank": 7

}

```

이 데이터를 불러오기 위해 JavaScript의 직접적인 HTTP 통신을 사용하면 교차 출처 요청이 차단되어 오류가 발생한다.

```javascript

var xmlhttp = new XMLHttpRequest();

xmlhttp.open('GET', 'http://server.example.com/Users/1234', true);

xmlhttp.onload = function () {

console.log('Retrieved Data: ' + xmlhttp.responseText);

};

xmlhttp.send(); // -> 교차 출처 요청 차단

```

반면, script 태그에 JSON 데이터를 직접 삽입하면 교차 출처 정책과 관계없이 데이터를 불러올 수 있지만, JavaScript 문법 오류가 발생한다.

```html



```

이는 웹 브라우저의 JavaScript 엔진이 변수, 상수 정의 등의 특정한 상황 없이 나오는 중괄호 문법을 블록으로 해석하기 때문이다.

JSONP는 이러한 웹 브라우저의 특성을 이용해 JSON 데이터를 클라이언트가 지정한 콜백 함수를 호출하는 유효한 JavaScript 문법으로 감싸 클라이언트에 전송한다.

클라이언트가 'parseResponse'라는 함수를 JSONP 요청의 콜백 함수로 지정하였다고 하면, 다음과 같은 HTML 태그가 문서에 삽입된다.

```html



```

외부 서비스 `server.example.com`은 다음과 같이 JSON 데이터를 패딩하여 클라이언트에 보낸다.

```javascript

parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});

```

웹 브라우저는 이 데이터를 유효한 JavaScript 프로그램으로 받아들여 실행하고, 콜백 함수인 `parseResponse`가 실행되며 받아온 데이터를 처리할 수 있게 된다.

JSONP에서 `<script>` 요소의 `src` 속성이 가리키는 URL 요청은 JSON 데이터와 함께 JavaScript 코드(일반적으로 함수 호출)가 래핑되어 반환된다. 관례적으로, JSON 데이터를 제공하는 서버는 요청하는 웹사이트에 JSONP 함수 이름을 지정하도록 제안하며, 일반적으로 서버에 대한 요청에서 `jsonp` 또는 콜백을 쿼리 문자열 매개변수로 사용한다.[3]

2. 2. 콜백 함수

웹 브라우저에서 실행되는 JavaScript는 동일 출처 정책에 따라 외부 출처에서 데이터를 직접 받아오는 것이 불가능하지만, `

```

`callback` 파라미터는 서버와 클라이언트 간에 미리 정해진 이름으로, 서버는 이 파라미터 값을 확인하여 해당 이름의 함수 호출문으로 JSON 데이터를 감싼다. 예를 들어, 외부 서비스 `server.example.com`은 다음과 같이 JSON 데이터를 패딩하여 클라이언트에 보낸다.

```javascript

parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});

```

웹 브라우저는 이 데이터를 유효한 JavaScript 프로그램으로 받아들여 실행하고, 콜백 함수인 `parseResponse`가 실행되며 받아온 데이터를 처리할 수 있게 된다. 즉, JSONP에서 `parseResponse()` 함수 호출은 JSON 데이터 주위의 "패딩" 또는 "접두사" 역할을 한다.[3]

일반적으로 JSONP를 사용하려면 서버가 JSONP 함수를 포함하는 응답으로 응답해야 하며, JSON 형식의 결과만으로는 작동하지 않는다. 전송되는 JSONP 함수 호출과 함수가 수신하는 페이로드는 클라이언트와 서버 간에 합의되어야 한다. 관례적으로, JSON 데이터를 제공하는 서버는 요청하는 웹사이트에 JSONP 함수 이름을 지정하도록 제안하며, 일반적으로 서버에 대한 요청에서 `jsonp` 또는 콜백이라는 이름의 쿼리 문자열 매개변수를 사용한다.

2. 3. 데이터 처리

웹 브라우저에서 실행되는 JavaScript는 동일 출처 정책에 따라 XMLHttpRequest 등의 직접적인 HTTP 통신을 이용해 외부 출처에서 데이터를 받아오는 것이 불가능하지만, HTML `<script>` 요소는 외부 출처로부터 조회된 내용을 실행하는 것이 허용되어 있다.[3]

JSONP는 이러한 웹 브라우저의 특성을 이용해, JSON 데이터를 클라이언트가 지정한 콜백 함수를 호출하는 유효한 JavaScript 문법으로 감싸 클라이언트에 전송한다.

클라이언트가 'parseResponse'라는 함수를 JSONP 요청의 콜백 함수로 지정하였다고 하면, 다음과 같은 HTML 태그가 문서에 삽입된다.

```html



```

외부 서비스 `server.example.com`은 다음과 같이 JSON 데이터를 패딩하여 클라이언트에 보낸다.[3]

```javascript

parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});

```

웹 브라우저는 이 데이터를 유효한 JavaScript 프로그램으로 받아들여 실행하고, 콜백 함수인 parseResponse가 실행되며 받아온 데이터를 처리할 수 있게 된다.

일반적으로 JSONP 요청의 `src` 속성에 지정하는 URL에 해당 함수의 이름을 쿼리 문자열 형식으로 추가하며, 이때 지정하는 함수 이름은 웹 페이지 측에서 이미 정의되어 있는 콜백용 함수의 이름이 된다. 함수 이름을 전달하는 요청 매개변수의 이름은 서버와 클라이언트 간에 사전에 정해져 있어야 한다.

예를 들어, `callback`이라는 매개변수 이름으로 `parseResponse`라는 함수 이름을 전달하는 경우,

```javascript



```

위와 같은 요청에 대한 응답으로 JSON 형식의 데이터를 인수로 하는 함수 호출문이 반환된다. 이 함수 호출문이 브라우저에 의해 해석 및 실행됨으로써 데이터 수신 완료와 콜백 처리가 가능해진다.

3. 기능

웹 브라우저에서 실행되는 JavaScript는 동일 출처 정책에 따라 XMLHttpRequest 등의 직접적인 HTTP 통신을 이용해 외부 출처에서 데이터를 받아오는 것이 불가능하지만, HTML `<script>` 요소는 외부 출처로부터 조회된 내용을 실행하는 것이 허용되어 있다. JSONP는 이러한 웹 브라우저의 특성을 이용해, JSON 데이터를 클라이언트가 지정한 콜백 함수를 호출하는 유효한 JavaScript 문법으로 감싸 클라이언트에 전송한다.[3]

예를 들어, 외부 서비스 `http://server.example.com/Users/1234`에서 사람 Foo의 기록을 JSON 포맷으로 반환한다고 가정해 보자.

```json

{

"Name": "Foo",

"Id": 1234,

"Rank": 7

}

```

이 데이터를 불러오기 위해 JavaScript의 직접적인 HTTP 통신을 사용하면 오류가 발생한다.

```javascript

var xmlhttp = new XMLHttpRequest();

xmlhttp.open('GET', 'http://server.example.com/Users/1234', true);

xmlhttp.onload = function () {

console.log('Retrieved Data: ' + xmlhttp.responseText);

};

xmlhttp.send(); // -> 교차 출처 요청 차단

```

반면 `script` 태그에 JSON 데이터를 직접적으로 삽입하면 JSON 데이터를 교차 출처 정책에 관계 없이 불러올 수 있지만 JavaScript 문법 오류가 발생한다.

```html



```

이는 웹 브라우저의 JavaScript 엔진이 변수, 상수 정의 등의 특정한 상황 없이 나오는 중괄호 문법을 block으로 해석하기 때문이다.

JSONP는 JSON 데이터를 클라이언트가 지정한 콜백 함수를 호출하는 JavaScript 문법으로 감싸서 전송한다. 클라이언트가 'parseResponse'라는 함수를 JSONP 요청의 콜백 함수로 지정하였다고 하면, 다음과 같은 HTML 태그가 문서에 삽입된다.

```html



```

외부 서비스 server.example.com은 다음과 같이 JSON 데이터를 패딩하여 클라이언트에 보낸다.

```javascript

parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});

```

웹 브라우저는 이 데이터를 유효한 JavaScript 프로그램으로 받아들여 실행하고, 콜백 함수인 parseResponse가 실행되며 받아온 데이터를 처리할 수 있게 된다.

웹 브라우저는 "동일 출처 정책"이라는 제약으로 인해 웹 페이지는 일반적으로 자신을 생성한 도메인 이외의 도메인의 서버와 통신할 수 없다. 그러나 HTML의 script 태그의 src 속성에는 다른 도메인의 URL을 지정하여 통신할 수 있다는 점을 이용하여 다른 도메인의 서버에서 데이터를 가져오는 것이 가능해진다.

JSONP에서는 일반적으로 위 src 속성의 응답 내용은 JavaScript 함수 호출 형식이 되므로 `src` 속성에 지정하는 URL에 해당 함수의 이름을 쿼리 문자열 형식으로 추가한다. 일반적인 방법으로는 이 때 지정하는 함수 이름은 웹 페이지 측에서 이미 정의되어 있는 콜백용 함수의 이름이 된다. 함수 이름을 전달하는 요청 매개변수의 이름은 서버와 클라이언트 간에 사전에 정해져 있어야 한다.

예를 들어 ( `callback`이라는 매개변수 이름으로 `parseResponse`라는 함수 이름을 전달하는 경우)

```javascript



```

일반적으로는 위 요청의 응답으로 JSON 형식의 데이터를 인수로 하는 함수의 호출문이 반환된다. 이 함수 호출문이 브라우저에 의해 해석·실행됨으로써 데이터 수신 완료의 감지와 콜백 처리가 가능해진다. 위의 예에서는 `parseResponse`라는 함수 호출문이 반환된다.

```javascript

parseResponse({"Name":"Smith","Rank":7})

```

교차 출처 리소스 공유(CORS)가 채택되기 전에는 다른 출처의 데이터를 공유할 수 없었지만, JSONP를 통해 우회적으로 데이터를 가져올 수 있었다.

4. Script 요소 삽입

웹 브라우저에서 실행되는 JavaScript는 동일 출처 정책에 따라 XMLHttpRequest 등의 직접적인 HTTP 통신을 이용해 외부 출처에서 데이터를 받아오는 것이 불가능하지만, HTML `<script>` 요소는 외부 출처로부터 조회된 내용을 실행하는 것이 허용되어 있다. JSONP는 이러한 웹 브라우저의 특성을 이용한다.

JSONP 요청은 일반적으로 JavaScript 헬퍼 라이브러리(예: jQuery)를 사용하여 수행된다. 새로운 JSONP 요청마다 브라우저는 새로운 `<script>` 요소를 추가하거나 기존 요소를 재사용한다. 새로운 스크립트 요소를 추가하는 방식은 동적 DOM 조작을 통해 이루어지며, 이를 ''스크립트 요소 삽입''이라고 한다. `<script>` 요소는 HTML DOM에 삽입되며, 원하는 JSONP 엔드포인트의 URL이 "src" 속성으로 설정된다.

jQuery를 사용하여 JSONP 호출을 위해 스크립트 요소를 동적으로 삽입하는 예는 다음과 같다.

```javascript

$.getScript("http://server.example.com/Users/192.168.73.96?callback=parseResponse");

```

요소가 삽입된 후, 브라우저는 해당 요소를 평가하고, src URL에 대해 HTTP GET을 수행하여 내용을 검색한다. 그런 다음 브라우저는 반환된 페이로드를 JavaScript로 평가하는데, 이는 일반적으로 함수 호출이다. 이러한 방식으로 JSONP를 사용하면 브라우저 페이지가 스크립트 요소 삽입을 통해 동일 출처 정책을 우회할 수 있다.[4]

JSONP에서는 일반적으로 `<script>` 태그의 `src` 속성에 지정하는 URL에 콜백 함수의 이름을 쿼리 문자열 형식으로 추가한다. 예를 들어, `callback`이라는 매개변수 이름으로 `parseResponse`라는 함수 이름을 전달하는 경우 다음과 같은 HTML 태그가 문서에 삽입된다.

```html



```

외부 서비스는 다음과 같이 JSON 데이터를 패딩하여 클라이언트에 보낸다.

```javascript

parseResponse({"Name":"Smith","Rank":7})

```

웹 브라우저는 이 데이터를 유효한 JavaScript 프로그램으로 받아들여 실행하고, 콜백 함수인 `parseResponse`가 실행되며 받아온 데이터를 처리할 수 있게 된다.

5. 보안 문제점

JSONP는 다른 도메인의 서버와 통신할 수 있게 해주지만, 다음과 같은 보안 취약점을 가지고 있어 사용에 주의해야 한다.


  • 신뢰할 수 없는 코드 주입: JSONP를 사용하면 원격 서버가 웹사이트에 어떤 내용이든 주입할 수 있다. 원격 서버에 취약점이 있다면, 공격자는 악성 코드를 삽입하여 사용자 정보를 탈취하거나 웹사이트를 손상시킬 수 있다.[5]
  • 사이트 간 요청 위조 (CSRF/XSRF): 악의적인 사용자가 조작된 요청을 보내 사용자가 의도하지 않은 작업을 수행하게 만드는 공격이다. JSONP는 HTML `<script>` 태그를 사용하는데, 이 태그는 동일 출처 정책을 따르지 않는다. 따라서 악성 페이지는 다른 사이트의 JSONP 엔드포인트를 호출하여 사용자의 민감한 정보를 탈취할 수 있다.[12]
  • 콜백 함수 이름 조작 및 반사 파일 다운로드(RFD) 공격: 서버에서 반환되는 콜백 함수 이름을 위생 처리하지 않으면 악성 스크립트가 실행될 수 있다. 이는 2014년 RFD 공격에서 `application/json` 콘텐츠 유형 관련 제약 사항을 우회할 수 있음이 입증되었다.[10]
  • 로제타 플래시 (Rosetta Flash): 어도비 플래시 플레이어(Adobe Flash Player)의 취약점을 이용한 공격이다. 2014년에 발견되어 구글, 유튜브, 트위터 등 많은 유명 웹사이트에 영향을 미쳤다.[13]


이러한 보안 문제 때문에, 최신 웹 개발에서는 JSONP 대신 교차 출처 리소스 공유(CORS)와 같은 더 안전한 방법을 사용하는 것이 일반적이다.

5. 1. 신뢰할 수 없는 제3자 코드

원격 서버의 스크립트 요소를 포함하면 원격 서버가 웹사이트에 어떤 내용이든 주입할 수 있다. 원격 서버에 JavaScript 주입을 허용하는 취약점이 있는 경우, 원래 서버에서 제공되는 페이지는 더 큰 위험에 노출된다. 공격자가 원래 웹 페이지에 JavaScript를 주입할 수 있다면, 해당 코드는 동일 출처 정책을 우회하여 어떤 도메인에서든 추가 JavaScript를 검색할 수 있다.[5] 콘텐츠 보안 정책 HTTP 헤더를 사용하면 웹사이트에서 웹 브라우저에 스크립트를 포함할 수 있는 도메인을 알릴 수 있다.

5. 2. 공백 문자 차이

JSONP는 `eval()`을 사용하여 JSON을 해석하는 것과 동일한 문제점을 가지고 있었는데, 둘 다 JSON 텍스트를 JavaScript로 해석하기 때문에, JSON 자체에서 U+2028 (줄 구분자) 및 U+2029 (문단 구분자)를 처리하는 방식에 차이가 있었다. 이로 인해 일부 JSON 문자열은 JSONP에서 유효하지 않게 되었고, JSONP를 제공하는 서버는 전송 전에 이러한 문자를 이스케이프 처리해야 했다.[8] 이 문제는 ES2019에서 해결되었다.[9]

5. 3. 콜백 이름 조작 및 RFD 공격

JSONP는 클라이언트가 지정한 콜백 함수를 호출하는 JavaScript 문법으로 JSON 데이터를 감싸서 전송하는데, 이는 웹 브라우저가 변수나 상수 정의 없이 나오는 중괄호({})를 블록으로 해석하여 JSON 데이터를 `