사기 및 악용 사례 방지

앱의 인기가 커질수록 앱을 악용하려는 악의적인 사용자의 관심을 끌 수도 있습니다. 이 주제에서는 결제 통합 공격을 방지하고 악용 사례가 앱에 미치는 영향을 줄이는 데 유용한 권장사항을 설명합니다.

민감한 로직을 백엔드로 이동

앱 디자인에서 허용하는 한, 민감한 데이터와 로직을 개발자가 제어하는 백엔드 서버로 이동합니다. 프런트엔드 기기에 저장한 데이터와 로직이 많을수록 수정 또는 변조에 훨씬 취약합니다.

예를 들어, 온라인 체스 게임은 프런트엔드에서 항상 합법적인 동작을 전송한다고 신뢰하는 대신에 백엔드에서 모든 동작을 확인해야 합니다.

또한, 시스템 디자인에 따라 취약성이나 보안 문제를 발견하면 프런트엔드보다는 백엔드에서 디버그하고 수정하며 업데이트를 출시하는 것이 더 쉬울 수 있습니다.

자격을 부여하기 전에 구매 확인

백엔드에서 처리해야 하는 민감한 데이터와 로직의 특별한 사례는 구매 확인입니다. 사용자가 구매한 후에는 다음을 실행해야 합니다.

  1. 상응하는 purchaseToken을 백엔드로 전송합니다. 즉, 모든 구매의 모든 purchaseToken 값을 기록으로 유지해야 합니다.
  2. 현재 구매의 purchaseToken 값이 이전의 purchaseToken 값과 일치하지 않는지 확인합니다. purchaseToken은 전역에서 고유하므로 이 값을 데이터베이스에서 기본 키로 안전하게 사용할 수 있습니다.
  3. Google Play Developer API의 Purchases.products:get 또는 Purchases.subscriptionsv2:get 엔드포인트를 사용하여 구매가 합법적인지 Google로 확인합니다.
  4. 구매가 합법적이며 과거에 사용되지 않았다면 인앱 상품 또는 정기 결제에 안전하게 자격을 부여할 수 있습니다.
  5. 또한, 정기 결제의 경우 Purchases.subscriptionsv2:getlinkedPurchaseToken이 설정될 때 데이터베이스에서 linkedPurchaseToken을 삭제하고 linkedPurchaseToken에 부여된 자격을 취소하여 여러 사용자에게 동일한 구매 자격이 부여되지 않도록 해야 합니다.
  6. 구매 상태가 PURCHASED인 경우에만 자격을 부여해야 하며 PENDING 구매를 올바르게 처리해야 합니다. CANCELED 상태가 급증하고 있다면 구매가 아직 PENDING 상태더라도 자격을 부여할 수 있습니다. 자세한 내용은 대기 중인 거래 처리를 참고하세요.
  7. 자격을 부여한 후 소비성 제품을 소비하고 확인하려면 보안 백엔드 서버에서 Purchases.products:consume Play Developer API를 사용하세요. 비소비성 제품 또는 정기 결제를 확인하려면 보안 백엔드 서버에서 관련 Play Developer API 엔드포인트인 Purchases.products:acknowledge 또는 Purchases.subscriptions:acknowledge를 호출합니다. 확인은 사용자가 구매에 대한 자격을 부여받았음을 Google Play에 알리므로 필요합니다. 자격을 부여한 직후 구매를 확인해야 합니다.

    앱을 통해 클라이언트 측에서 구매를 확인하거나 소비할 수 있지만 서버 측 API는 네트워크 연결 불량, 악의적인 활동과 같은 문제를 방지하기 위해 추가적인 보호 기능을 제공합니다. 예를 들어 사용자가 앱에서 상품을 구매했지만 구매 검증 과정에서 네트워크 연결이 끊겼다고 가정해 보겠습니다. 서버 확인이 없으면 앱을 통해 다시 로그인하여 확인 절차를 완료해야 할 수 있습니다. 그러지 않는 경우 사용자가 3일 이내에 다시 로그인하지 않으면 구매 확인 부족으로 인해 구매가 자동으로 환불됩니다. 서버 확인은 Google Play에서 서버에 구매가 유효함을 알리는 즉시 확인을 전송하여 이러한 시나리오를 방지합니다.

    구매 확인 및 소비에 관한 자세한 내용은 구매 처리를 참고하세요.

잠금 해제된 콘텐츠 보호

악의적인 사용자가 잠금 해제된 콘텐츠를 재배포하는 것을 방지하려면 콘텐츠를 APK 파일에 번들로 포함하지 마시기 바랍니다. 그 대신, 다음 방법 중 하나를 따르세요.

  • 실시간 서비스를 사용하여 콘텐츠 피드와 같은 콘텐츠를 제공합니다. 또한, 실시간 서비스를 통해 콘텐츠를 제공하면 콘텐츠를 최신 상태로 유지할 수 있습니다.
  • 원격 서버를 사용하여 콘텐츠를 제공합니다.

원격 서버나 실시간 서비스를 통해 콘텐츠를 제공하면 잠금 해제된 콘텐츠를 기기 메모리나 기기의 SD 카드에 저장할 수 있습니다. SD 카드에 콘텐츠를 저장하는 경우 콘텐츠를 암호화하고 기기별 암호화 키를 사용해야 합니다.

무효화된 구매 감지 및 처리

무효화된 구매는 취소되거나 지불이 거절된 구매입니다. 무효화된 구매에서 이전에 인앱 상품이나 기타 콘텐츠를 사용자에게 부여했다면 Voided Purchases API를 사용하여 회수할 수 있는 연결된 콘텐츠와 함께 구매가 무효화된 이유를 확인할 수 있습니다.

인앱 상품 및 정기 결제 구매는 다음과 같은 여러 이유로 무효화될 수 있습니다.

  • 사용자, 개발자 또는 Google에서 구매를 취소한 경우. 정기 결제의 경우 정기 결제 자체를 취소하는 것이 아니라 정기 결제의 구매를 취소하는 것입니다.
  • 구매가 지불 거절된 경우
  • 앱 개발자가 사용자 주문을 취소하거나 환불하고 콘솔에서 '취소' 옵션을 선택한 경우

무효화된 구매의 이유 및 사용자의 이전 행동 데이터를 고려하여 어떻게 조치할지 결정할 수 있습니다. 다음 중 하나 이상을 구현하는 것이 좋습니다.

  • 회수 실행: 구매가 무효화되면 구매한 적이 없는 것처럼 미사용 상품을 회수할 수 있습니다. 예를 들어, 인게임 화폐 구매가 무효화되면 사용자에게 이미 부여된 화폐를 회수할 수 있습니다. 사용자가 이미 화폐를 사용한 경우에는 화폐 잔액을 마이너스로 설정하고 화폐 잔액이 마이너스를 벗어날 때까지 앱 활동 및 향후 구매를 제한하는 것이 좋습니다.
  • 여러 차례 위반에 관한 구현: 인앱 경고 표시와 같이 최초 위반자에게는 덜 강경한 조치를 취하는 것이 좋습니다. 반복적인 위반자의 경우 더 심각한 조치를 고려합니다.
  • 일시적 구매 중지: 여러 차례 위반에 관한 구현과 마찬가지로 구매가 무효화된 이유를 더 철저하게 조사할 수 있을 때까지 구매를 무효화한 사용자의 구매를 중지하는 것이 좋습니다.
  • 일시적 또는 영구적으로 앱 액세스 차단: 반복적이고 악의적인 활동을 하는 극단적인 경우에는 일시적 또는 영구적으로 앱 액세스를 차단하는 것이 좋습니다.
  • Voided Purchases API의 빈번한 호출: 하나 이상의 무효화된 구매를 감지했다면 Voided Purchases API를 더 자주 호출하여 사용자가 구매를 소비하기 전에 회수하는 것이 좋습니다. Voided Purchases API 문서에서 Voided Purchases API 할당량에 관한 자세한 내용을 확인할 수 있습니다.

사기가 발생하기 전에 Google이 감지하도록 돕기

일부 사기 유형은 여러 개의 Google 및 인앱 계정을 만들어서 활동을 숨기는 악의적인 사용자와 관련이 있습니다.

BillingFlowParams 빌더에서 setObfuscatedAccountIdsetObfuscatedProfileId 메서드를 사용하면 Google이 Google 계정을 인앱 계정에 매핑하는 데 도움이 됩니다.

Google은 이 데이터를 사용하여 의심스러운 행동을 감지하고 거래가 완료되기 전에 일부 유형의 사기 거래를 차단합니다.

상표권 및 저작권 침해에 관한 조치

원격 서버를 사용하여 콘텐츠를 전송 또는 관리하고 있다면 사용자가 콘텐츠에 액세스할 때마다 앱에서 잠금 해제된 콘텐츠의 구매 상태를 확인하도록 합니다. 이렇게 하면, 필요할 때 사용을 취소하고 불법 복제를 최소화할 수 있습니다. 자신의 콘텐츠가 Google Play에서 재배포되는 것을 발견했다면 신속하고 단호하게 조치를 취해야 합니다. 자세한 내용은 저작권 고객센터의 저작권 FAQ 페이지를 참조하세요.