Stripe is Silently Recording Your Movements On its Customers' Websites

Michael Lynch

Stripe가 고객사 웹사이트에서 당신의 움직임을 몰래 기록하고 있다

원문은 Michael Lynch님이 에 게재했습니다. 이 블로그 구독하기

스타트업과 테크 기업 사이에서 Stripe는 결제 처리를 위한 거의 보편적인 선택처럼 보인다. 새로 만든 웹 앱에 유료 구독 기능을 넣어야 했을 때 Stripe가 당연한 선택처럼 느껴졌다. 하지만 연동을 마친 뒤, Stripe의 공식 JavaScript 라이브러리가 내 사이트에서의 모든 탐색 활동을 기록해 Stripe에 전송한다는 사실을 알게 됐다. 수집되는 데이터는 다음과 같다:

  1. Stripe 결제 폼이 전혀 표시되지 않는 페이지를 포함해, 사용자가 내 사이트에서 방문하는 모든 URL
  2. 사용자가 내 사이트를 탐색하는 동안 마우스 커서를 어떻게 움직이는지에 대한 텔레메트리
  3. Stripe를 통해 결제를 받는 다른 사이트와 내 사이트 방문자를 연결할 수 있게 하는 고유 식별자

이 글에서는 내가 발견한 내용과 영향을 받는 대상, 그리고 웹 애플리케이션에서 Stripe의 데이터 수집을 제한하는 방법을 공유한다.

누가 영향을 받나?

다음 중 하나라도 해당하면 Stripe는 당신의 웹사이트에서 이 데이터를 수집한다:

  • 기본 페이지 템플릿에 Stripe 스크립트 태그가 포함된 경우:
    • <script src="https://js.stripe.com/v3">
  • 웹사이트가 React, Vue, Angular 등으로 만든 싱글 페이지 앱이며 Stripe로 결제를 처리하는 경우.

발견 경위

유료 요금제를 포트폴리오 리밸런서에 추가하던 중 우연히 이 사실을 발견했다. 개발 과정에서 브라우저의 HTTP 트래픽을 검사할 수 있게 해주는 HTTP 프록시를 사용하고 있었다.

Stripe로 앱의 결제 흐름을 성공적으로 구현한 뒤, 페이지를 이동할 때마다 Stripe URL로 새로운 HTTP POST 요청이 생성되는 것을 발견했다:

앱에서 새 페이지를 방문할 때마다 Stripe.js 라이브러리가 Stripe에 보고한다

방문한 페이지 중 어느 곳에서도 Stripe 라이브러리를 호출하지 않았기 때문에 이상했다. 실제로 내 앱은 사용자가 계정을 생성하기 전까지 결제 정보를 수집하지 않는데, 쿠키나 저장된 자격 증명이 없는 완전한 신규 사용자로 앱 홈페이지에 접속했을 때도 Stripe가 HTTP 요청을 보내고 있었다.

Stripe는 무엇을 전송하고 있나?

Stripe가 생성한 모든 발신 요청은 다음과 같이 생겼다:

POST /4 HTTP/1.1
Host: m.stripe.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: text/plain;charset=UTF-8
Content-Length: 692
Origin: https://m.stripe.network
Connection: close
Referer: https://m.stripe.network/inner.html
Cookie: m=e29f7c00-b748-4e5f-8625-34d14dbc1c01; m=e29f7c00-b748-4e5f-8625-34d14dbc1c01

JTdCJTIydjIlMjIlM0ExJTJDJTIyaWQlMjIlM0ElMjI4MTBiOWIxY2E3ODU5YzNlYzExYTY0NTI0NzNkMTZmYyUyMiUyQyUyMnQlMjIlM0E4JTJDJTIydGFnJTIyJTNBJTIyNC41LjIxJTIyJTJDJTIyc3JjJTIyJTNBJTIyanMlMjIlMkMlMjJhJTIyJTNBbnVsbCUyQyUyMmIlMjIlM0ElN0IlMjJhJTIyJTNBJTIyJTIyJTJDJTIyYiUyMiUzQSUyMmh0dHBzJTNBJTJGJTJGYXNzZXRyZWJhbGFuY2VyLmNvbSUyRnByaWNpbmclMjIlMkMlMjJjJTIyJTNBJTIyUG9ydGZvbGlvJTIwUmViYWxhbmNlciUyMiUyQyUyMmQlMjIlM0ElMjIxYjVhMDcxOS1jMTFjLTQwOTEtYWZiYi00NGE1MjRhMDM2ZGUlMjIlMkMlMjJlJTIyJTNBJTIyMWJhOTYwOWMtMjI0Ni00YjYwLTk1ZWUtYzg0YTRlNDhmOTkzJTIyJTJDJTIyZiUyMiUzQWZhbHNlJTJDJTIyZyUyMiUzQXRydWUlMkMlMjJoJTIyJTNBdHJ1ZSUyQyUyMmklMjIlM0ElNUIlMjJsb2NhdGlvbiUyMiU1RCUyQyUyMmolMjIlM0ElNUIlNUQlMkMlMjJuJTIyJTNBMTkzJTdEJTdE

하단에 표시된 JTdCJTIydj...로 시작하는 문자열은 URL 인코딩 및 base64 인코딩된 JSON 덩어리다. 다음 bash 명령어로 사람이 읽을 수 있는 문자열로 디코딩할 수 있다:

$ echo "JTdCJTIydjIlMjIlM0ExJTJDJTIyaWQlMjIlM0ElMjI4MTBiOWIxY2E3ODU5YzNlYzExYTY0NTI0NzNkMTZmYyUyMiUyQyUyMnQlMjIlM0E4JTJDJTIydGFnJTIyJTNBJTIyNC41LjIxJTIyJTJDJTIyc3JjJTIyJTNBJTIyanMlMjIlMkMlMjJhJTIyJTNBbnVsbCUyQyUyMmIlMjIlM0ElN0IlMjJhJTIyJTNBJTIyJTIyJTJDJTIyYiUyMiUzQSUyMmh0dHBzJTNBJTJGJTJGYXNzZXRyZWJhbGFuY2VyLmNvbSUyRnByaWNpbmclMjIlMkMlMjJjJTIyJTNBJTIyUG9ydGZvbGlvJTIwUmViYWxhbmNlciUyMiUyQyUyMmQlMjIlM0ElMjIxYjVhMDcxOS1jMTFjLTQwOTEtYWZiYi00NGE1MjRhMDM2ZGUlMjIlMkMlMjJlJTIyJTNBJTIyMWJhOTYwOWMtMjI0Ni00YjYwLTk1ZWUtYzg0YTRlNDhmOTkzJTIyJTJDJTIyZiUyMiUzQWZhbHNlJTJDJTIyZyUyMiUzQXRydWUlMkMlMjJoJTIyJTNBdHJ1ZSUyQyUyMmklMjIlM0ElNUIlMjJsb2NhdGlvbiUyMiU1RCUyQyUyMmolMjIlM0ElNUIlNUQlMkMlMjJuJTIyJTNBMTkzJTdEJTdE" \
  | base64 --decode \
  | python -c "import sys; import json; from urllib.parse import unquote; print(json.dumps(json.loads(unquote(sys.stdin.read())), indent=2, sort_keys=True))"
{
  "a": null,
  "b": {
    "a": "",
    "b": "https://assetrebalancer.com/pricing",
    "c": "Portfolio Rebalancer",
    "d": "1b5a0719-c11c-4091-afbb-44a524a036de",
    "e": "1ba9609c-2246-4b60-95ee-c84a4e48f993",
    "f": false,
    "g": true,
    "h": true,
    "i": ["location"],
    "j": [],
    "n": 193
  },
  "id": "810b9b1ca7859c3ec11a6452473d16fc",
  "src": "js",
  "t": 8,
  "tag": "4.5.21",
  "v2": 1
}

Stripe 라이브러리는 사용자가 내 앱에서 새 페이지를 볼 때마다 이와 같은 새로운 요청을 생성한다. 각 요청은 요청 시점의 주소 표시줄에 있는 URL을 URL 필드에 반영한다는 점을 제외하면 거의 비슷해 보인다. Stripe가 내 앱의 모든 페이지뷰를 기록하고 있는 것처럼 보였다. 더욱이 Stripe는 쿼리 파라미터와 URL 프래그먼트(예: /account?id=12345#name=michael)를 포함한 전체 URL을 기록하는데, 일부 웹사이트는 이러한 부분에 민감한 정보를 저장하기도 한다.

영상에서 눈치챘을 수도 있지만, 앱을 처음 로드했을 때 첫 페이지는 요청을 두 개 생성한 반면, 그 이후의 페이지 로드에서는 하나씩만 생성됐다. 두 번째 요청을 디코딩해보니 다음과 같았다:

{
  "data": [4669, 20, 26, 13, 21, 20, 40, 21, 25, 14],
  "muid": "1b5a0719-c11c-4091-afbb-44a524a036de",
  "sid": "1ba9609c-2246-4b60-95ee-c84a4e48f993",
  "source": "mouse-timings-10",
  "url": "https://assetrebalancer.com/"
}

mouse-timings라는 이름으로 보아 Stripe가 사용자의 마우스 움직임을 기록하고 있는 것으로 보인다.

마지막으로, 각 요청에는 사용자를 고유하게 식별하는 동일한 쿠키가 포함되어 있다:

Cookie: m=e29f7c00-b748-4e5f-8625-34d14dbc1c01

이 쿠키 덕분에 Stripe는 내 사용자가 Stripe를 연동한 웹상의 다른 사이트를 방문할 때, 결제 폼을 본 적이 없더라도 추적할 수 있다.

실수인가?

처음에는 분명 내 실수라고 생각했다. Stripe 연동에서 부주의한 실수를 해서 잘못 홈으로 전화하도록 만든 게 틀림없다고 여겼다.

원인을 조사하기 위해 앱에서 HTTP POST 요청을 받던 URL을 구글에 검색해 봤다:

https://m.stripe.com/4

내 코드에서 버그를 찾는 대신, 앱에서 이런 동작을 보고 놀란 다른 개발자들의 수십 개 게시물을 발견했다. 보고서는 2017년까지 거슬러 올라간다.

이 동작에 대한 이전 사용자 보고서를 모은 콜라주

개발자들은 수년간 StackOverflow와 GitHub에 Stripe의 추적 동작에 대해 게시해 왔다

GitHub의 한 이슈 스레드에서 Stripe 직원은 이 동작이 의도치 않았다고 언급하며 Stripe가 수정 방안을 찾겠다고 밝혔다:

GitHub에 남긴 Adam Solove의 댓글 스크린샷

GitHub 댓글에서 Stripe 직원은 Stripe.js가 앱이 라이브러리를 호출할 때, 그리고 사용자가 결제 정보를 제출하는 페이지에서만 데이터를 전송해야 한다고 제안한다.

그로부터 7개월이 지났지만, 해당 스레드나 내가 찾을 수 있는 다른 어디에서도 Stripe의 후속 조치는 없었다.

문제 확인하기

내 앱의 다른 요소가 이 동작을 유발하는 것이 아님을 확실히 하기 위해, 문제를 재현하는 최소한의 프로젝트를 만들었다. @stripe/stripe-js npm 패키지만 설치된 최소한의 Vue 앱이다.

실험 결과 다음 한 줄이 Stripe 라이브러리를 로드하고 사용자 추적을 시작하게 한다는 것이 확인됐다:

import { loadStripe } from "@stripe/stripe-js";

내 앱은 loadStripe 함수를 호출조차 하지 않았다는 점에 유의하자. Stripe.js는 클라이언트 앱이 라이브러리를 임포트하는 즉시 사용자 행동 추적을 시작한다. 싱글 페이지 앱의 경우 이는 최종 사용자가 웹사이트의 어떤 페이지를 로드하는 순간 발생한다.

참고: loadStripe는 오해의 소지가 있는 이름이다. 클라이언트 애플리케이션이 해당 함수를 호출하기 전에 이미 Stripe가 로드되기 때문이다. 더 적절한 이름은 ensureStripeIsLoaded일 것이다. 이 함수의 실제 역할은 Stripe 라이브러리 로드가 끝날 때까지 앱의 API 호출을 대기시키는 것이기 때문이다.

Stripe에 보고하기

Stripe 지원팀에 이 문제를 보고해 의도된 동작인지, 어떻게 방지할 수 있는지 문의했다.

Stripe는 사용자 추적이 의도된 설계이며, 오히려 이 기능을 환영해야 한다고 신속히 답변했다:

안녕하세요 Michael님,

문의해 주셔서 감사합니다. Stripe 지원팀의 Faith입니다.

바로 본론으로 들어가면, 확인하신 호출은 사기를 탐지하기 위한 의도된 동작이며 사용자에게 가장 이익이 되는 조치입니다. 문서에 따르면: “Stripe의 고급 사기 방지 기능을 최대한 활용하려면, 결제 페이지뿐만 아니라 모든 페이지에 이 스크립트를 포함하세요. 이를 통해 Stripe는 고객이 웹사이트를 탐색하는 동안 사기를 나타낼 수 있는 비정상적인 행동을 탐지할 수 있습니다.”

https://stripe.com/docs/js/including

다른 문제가 발생하거나 우려 사항이 있으면 언제든 알려주세요.

감사합니다,
Faith

“사용자에게 가장 이익이 되는”이라는 문구는 특히 오만하게 느껴졌다. 이 데이터 수집으로 가장 큰 이익을 얻는 쪽은 분명 사용자가 아니라 Stripe다. Stripe는 사기 탐지 모델을 학습시킬 무료 데이터를 얻고 있으며, 잠재적으로 그 정보를 광고주에게 판매할 수도 있다.

사용자 입장에서는 Stripe.js가 추가 JavaScript 라이브러리를 다운로드하도록 강제하고 브라우저에서 추가 HTTP 요청을 보내게 하여 경험을 저하시킨다. 이는 사용자가 신용카드 결제를 받는 페이지를 방문한 적이 없더라도 발생한다.

Stripe는 이를 고지하고 있나?

이 동작에 대한 Stripe의 공식 고지를 찾아봤지만 아무것도 찾을 수 없었다. 가장 가까운 것은 npm 패키지 설명에 있는 이 모호한 문단으로, Stripe 지원 담당자가 내게 인용한 내용이기도 하다:

Stripe의 고급 사기 방지 기능을 최대한 활용하려면, 결제 페이지뿐만 아니라 모든 페이지에서 Stripe.js가 로드되도록 하세요. 이를 통해 Stripe는 고객이 웹사이트를 탐색하는 동안 사기를 나타낼 수 있는 비정상적인 행동을 탐지할 수 있습니다.

개인정보 처리방침은 수집하는 데이터에 대해 조금 더 구체적이지만, 고객사 사이트가 아니라 stripe.com에서 데이터를 수집하는 것처럼 서술한다:

당사 사이트는 쿠키 및 기타 기술을 사용하여 효과적으로 기능합니다. 이러한 기술은 다음을 포함하여 당사 사이트 사용에 관한 정보를 기록합니다:

  • IP 주소, 기기 유형, 운영 체제 및 인터넷 브라우저 유형, 화면 해상도, 운영 체제 이름 및 버전, 기기 제조업체 및 모델, 언어, 플러그인, 애드온 및 방문 중인 사이트의 언어 버전과 같은 브라우저 및 기기 데이터;
  • 사이트에서 보낸 시간, 방문한 페이지, 클릭한 링크, 언어 기본 설정, 그리고 귀하를 당사 사이트로 유도하거나 리퍼한 페이지와 같은 사용 데이터.

또한 당사는 시간 경과에 따라 웹사이트 및 연결된 기기에서, 그리고 제3자 웹사이트, 기기, 앱 및 기타 온라인 기능과 서비스 전반에 걸쳐 귀하의 온라인 활동에 관한 정보를 수집할 수도 있습니다.

더 우려스러운 점은 개인정보 처리방침에 이 데이터를 광고주에게 판매할 수 있도록 허용하는 느슨한 문구가 포함되어 있다는 것이다:

귀하가 당사 사이트 또는 온라인 서비스를 방문할 때, 당사와 특정 제3자는 시간이 지남에 따라 그리고 여러 사이트에 걸쳐 귀하의 온라인 활동에 관한 정보를 수집하여 귀하의 개별 관심사에 맞춘 제품 및 서비스에 대한 광고(이러한 유형의 광고를 “관심사 기반 광고”라고 함)를 제공합니다.

완화 방법

사이트 소유자가 Stripe의 침해적인 추적을 막으려면 두 가지 문제를 해결해야 한다:

  1. 사용자가 결제가 필요한 페이지에 도달할 때까지 Stripe 라이브러리 실행을 지연하기
  2. 사용자가 결제를 완료한 뒤 Stripe 라이브러리 언로드하기.

첫 번째 문제 해결: Stripe 스크립트 로딩 지연하기

위에서 언급했듯이, Stripe는 앱이 라이브러리를 임포트하는 즉시 실행을 시작한다. 일부 개발자는 비동기 래퍼 함수를 추가하거나 코드 스플리팅을 사용해 의도적으로 이 동작을 방지한다.

다행히 지난주에 공개된 stripe-js v1.4.0 릴리스는 더 깔끔한 해결책을 제공한다. 이번 업데이트에서는 클라이언트가 부작용 없이 Stripe를 임포트할 수 있게 하는 @stripe/stripe-js/pure 임포트 경로가 도입됐다:

import { loadStripe } from "@stripe/stripe-js/pure";

이렇게 하면 앱이 loadStripe 함수를 명시적으로 호출할 때까지 Stripe 라이브러리 실행이 지연된다. loadStripe 함수 호출을 Stripe 결제가 관련된 페이지나 컴포넌트로만 제한하면, Stripe는 해당 페이지에서만 로드되므로 탐색 세션 초반의 사용자 추적을 방지할 수 있다.

두 번째 문제 해결: 결제 후 Stripe 언로드하기

Stripe 라이브러리 로드를 지연하는 것은 절반의 싸움에 불과하다. 결제 시점에만 Stripe를 로드하더라도, 해당 JavaScript는 앱에 남아 세션이 끝날 때까지 사용자를 계속 추적한다. 이를 방지하려면 고객의 결제가 완료됐을 때 앱이 Stripe를 강제로 언로드해야 한다.

안타깝게도 Stripe는 라이브러리를 언로드하거나 사용자 모니터링을 비활성화하는 공식적인 방법을 제공하지 않는다. 한 열정적인 개발자는 모든 Stripe 코드를 강제로 언로드하는 JavaScript 스니펫을 만들었지만, 이는 React 전용이며 언제든지 변경될 수 있는 Stripe 라이브러리의 문서화되지 않은 속성에 의존하므로 본질적으로 취약한 해결책이다.

나는 사용자가 결제 페이지를 벗어날 때 HTTP 리로드를 강제하는 방식으로 내 앱에서 이 문제를 해결했다. Vue에서는 페이지를 떠나기 전에 beforeRouteLeave 훅이 실행된다. 라우팅 과정을 중단시키고 다음 경로에 대해 전체 HTTP 요청을 강제하는 훅을 추가했다:

beforeRouteLeave(to) {
  // Force an HTTP request instead of a JavaScript route change because we need
  // a new page load that does *not* import Stripe.
  window.location.replace(to.path);
}

(신규) 사용자 추적 비활성화

추가: 2020년 4월 30일

내 글이 처음 공개된 후, Stripe는 JavaScript 라이브러리를 업데이트해 추적을 완전히 비활성화할 수 있는 새로운 파라미터를 포함시켰다. 이 옵션은 @stripe/stripe-js v1.5.0부터 사용할 수 있다:

import { loadStripe } from "@stripe/stripe-js/pure";

loadStripe.setLoadParameters({ advancedFraudSignals: false });
const stripe = await loadStripe("pk_test_TYooMQauvdEDq54NiTphI7jx");

이는 반가운 옵션이지만, 단점은 기능이 전부 아니면 전무라는 점이다. 사기 탐지를 활성화하면, 페이지 리로드를 강제하지 않는 한(위 참조) Stripe 거래가 완료된 후에도 이를 끌 수 없다.

(선택) 심층 방어를 위한 Content Security Policy

앞선 두 단계만으로 Stripe의 추적을 방지하기에 충분하다. 추가 보호를 위해 Content Security Policy(CSP)를 적용해 Stripe를 결제 페이지로만 제한할 수 있다.

내 앱에서는 이렇게 보인다:

일반 페이지 대비 결제 페이지의 CSP 헤더 스크린샷

Portfolio Rebalancer는 페이지별 Content Security Policy를 사용해 앱에서 결제 페이지를 제외한 어디에서도 Stripe가 로드되지 않도록 방지한다.

싱글 페이지 앱에서 페이지별 CSP를 구현하는 것은 다소 까다로운데, 브라우저가 기본적으로 사용자가 새 페이지로 이동할 때 서버에 새로운 정책을 조회하지 않기 때문이다. 정책 새로고침을 강제하기 위해 Vue의 beforeRouteEnter 가드를 결제 페이지에서 사용해 페이지가 로드될 때 새로운 HTTP 요청을 강제한다.

beforeRouteEnter(to, from) {
  // If we're landing on this page from another route, force an HTTP request
  // so that we retrieve the route-specific Content Security Policy header.
  if (from.matched.length > 0) {
    window.location.replace(to.path);
  }
}

Stripe를 방해하기 위해서만 CSP를 구현하는 것은 그만한 가치가 없을 수도 있지만, 이미 작동하는 정책이 있다면 Stripe 라이브러리가 결제 페이지에서만 실행된다는 추가적인 보장을 제공한다.

데모 사이트

실제 사이트에서 Stripe의 동작을 확인하려면, 이 동작을 보여주는 최소한의 Vue 앱을 만들었다:

요약

Stripe를 이용해 결제를 받는 웹사이트는 대개 애플리케이션 내에 Stripe의 JavaScript 라이브러리를 포함한다. Stripe 문서에 따라 연동하면, Stripe와 상호작용하거나 결제 폼을 표시하지 않는 페이지에서도 사용자의 탐색 세션 전체에 걸쳐 라이브러리가 사용자 추적 데이터를 Stripe와 공유하게 된다. 이 데이터는 다음을 포함한다:

  • 쿼리 파라미터와 URL 프래그먼트를 포함한, 사용자가 방문한 각 페이지의 전체 URL
  • 사용자가 탐색 중 마우스를 얼마나 빠르게 움직이는지에 대한 타이밍
  • 웹 전반에서 동일한 사용자를 추적할 수 있게 하는 쿠키

Stripe는 이러한 데이터 수집에 대해 명확히 고지하지 않으며, 클라이언트 애플리케이션이 라이브러리의 추적 동작을 제한하기 어렵게 만든다.

비공식적으로 문제를 논의할 때 Stripe는 데이터를 사기 방지 및 진단 목적으로만 사용한다고 공개적으로 밝힌 바 있다. 하지만 개인정보 처리방침의 문구는 마케팅 목적으로도 사용하거나 판매할 수 있음을 시사한다.

Stripe에 대한 권고

Stripe가 보안과 개인정보 보호를 얼마나 심각하게 여기는지를 고려하면, 그토록 많은 데이터를 투명성 없이 고객으로부터 수집해 왔다는 사실은 놀랍다. 너무 적은 고객만이 이를 알아챘기 때문에 지속된 단순한 부주의이길 바란다.

Stripe가 이 상황을 바로잡기 위해 취할 수 있는 조치는 다음과 같다:

  • 데이터 공유를 명확히 고지한다.
    • npm 패키지 페이지와 Stripe.js 문서는 클라이언트 애플리케이션이 라이브러리를 연동할 때 어떤 탐색 및 텔레메트리 데이터가 라이브러리에서 Stripe로 전송되는지 명확히 정의해야 한다.
  • 라이브러리 언로드를 지원한다.
    • 클라이언트 애플리케이션이 사용자의 결제를 수집한 뒤 Stripe를 언로드할 수 있는 공식 메커니즘을 제공해야 한다.
  • 옵트인 방식으로 클라이언트 애플리케이션이 공유할 데이터를 제어하게 한다.
    • Stripe 고객사는 애플리케이션에 대한 차지백 비용을 부담하므로, 차지백을 줄이기 위해 Stripe와 얼마나 많은 정보를 공유할지 직접 결정해야 한다.

업데이트: 2020년 4월 21일 오후 2시 47분(동부 시간)

Stripe 공동 창업자 Patrick Collison은 이 글에 답변하며 수집된 데이터를 사기 탐지 목적으로만 사용하겠다는 Stripe의 약속을 재확인했다. 그는 Stripe가 데이터 수집 관행과 관련한 서비스 약관의 문구를 곧 명확히 할 것이라고 덧붙였다.

정정: 이 글은 원래 “Stripe를 이용해 결제를 받는 웹사이트는 Stripe의 JavaScript 라이브러리를 반드시 포함해야 한다”고 서술했지만, Collison은 Stripe JS 라이브러리를 사용하지 않고도 Stripe와 연동하는 것이 가능하므로 이는 정확하지 않다고 지적했다.

업데이트: 2020년 4월 30일

Stripe는 개인정보 처리방침과 개발자 문서를 개정하고 연동자가 추적 동작을 제한할 수 있도록 하는 기능을 JavaScript 라이브러리에 추가했다.

Stripe의 변경 사항이 내가 제기한 우려를 어떻게 해소하는지 논의하는 후속 글을 게시했다:

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.

댓글