蘋果應用內支付(iOS IAP)的流程與常用攻擊方式


1. 客戶端直接verify蘋果的receipt 如果verify成功 自行發放商品 

2. 客戶端將receipt傳給server,由server進行驗證並發放商品

 

 

 

按照安全性原則, 客戶端的所有信息都是不可信的,而且支付是業務中的核心模塊,所以應該選擇第二種。

 

下面簡要介紹下,第二種方式的簡單流程。

 

1. 客戶端支付成功,拿到receipt

2. 客戶端將receipt傳到服務端 

3. 服務端去apple驗證receipt 如果驗證成功 就發放receipt中的商品

 

 

 

支付安全性

 

作為支付,安全性是第一位的,下面簡要分析一下常用的攻擊手段。

 

1、劫持apple server攻擊 => 通過dns污染,讓客戶端支付走到假的apple_server,並返回驗證成功的response。 這個主要針對支付方式一 如果是支付方式二 就無效。

2、重復驗證攻擊 => 一個receipt重復使用多次

3、跨app攻擊 => 別的app的receipt用到我們app中來

4、換價格攻擊 => 低價商品代替高價商品

5、歧義攻擊 => iap支付之前的status=0表示verify成功 而現在變為status=0只能表示receipt合法 具體支付詳情需要通過in_app字段決定 For iOS 6 style transaction receipts, the status code reflects the status of the specific transaction’s receipt.

6、中間人攻擊 => 偽造apple_server,如果用戶支付就將

 

劫持apple server攻擊

 

通過dns污染,讓客戶端通過假的apple_server進行verify,從而認為自己支付成功。這個主要針對**支付方式一**,如果是支付方式二,就沒效果了。常見的iap hack軟件@iAPFree @iAP Cracker 就是用的類似原理。

 

 

 

重復驗證攻擊

 

因為同一個receipt,如果第一次驗證成功,那么之后每次驗證都會成功。如果服務端沒有判重機制,就會導致一個receipt被當做多次充值處理。

 

為了預防這種情況,我們可以將receipt做一次md5得到receipt_md5, 每次發送充值請求的時候就按照receipt_md5判重,如果重復就停止商品發放。

 

 

 

app攻擊

 

通過在別的app中拿到receipt,然后發送到我們app中。因為這個receipt是合法的而且apple不會驗證請求的源,所以這個receipt是可以驗證通過的。

 

對於這種情況,我們可以判斷apple verify的返回值apple_callback_data中對應的bundle_id和我們app的bundle_id是否一樣來進行驗證。

 

 

 

換價格攻擊

 

在同一個app中,用低價商品的receipt偽造購買高價商品。這時候bundle_id和我們app的bundle_id是一致的。

 

針對這種情況, 我們可以從apple verify的返回值apple_callback_data中拿到對應的PRoduct_id, 並按照product_id來進行充值。 **不要信任客戶端的product_id**

 

 

 

歧義攻擊

 

在iOS6的時候,status=0表示此次支付成功,而現在變為status=0只表示receipt**整體上**合法。

 

所以,對iOS7即使是一個過期訂單,也會返回status=0,如果還按照iOS6的邏輯處理,就會導致假充值。針對iOS7,我們應該不只通過status,還要通過in_app中的內容,來決定如何發放商品。

```

For iOS 6 style transaction receipts, the status code reflects the status of the specific transaction’s receipt.

 

For iOS 7 style app receipts, the status code is reflects the status of the app receipt as a whole. For example, if you send a valid app receipt that contains an expired subscription, the response is 0 because the receipt as a whole is valid.

 

 

 

中間人攻擊

 

偽造apple server,將我們的支付請求轉發到真的apple_server,拿到合法的receipt,並弄個假的receipt給客戶端。這樣就拿到一個合法的憑證。利用這個合法的receipt,偽造別人充值的請求,從而達到幫別人充值的目的。

 

針對中間人攻擊,最重要的是保證a用戶的支付receipt,不能被b用戶使用。但是apple為了保護隱私,receipt中沒有任何用戶的個人信息,這就需要我們自己來保證。目前我們用加密的手段來做這個保證。

 

 

 

iOS支付的詳細流程

 

客戶端拿到apple的receipt 並發送到serverserver拿到這個receipt,向蘋果驗證得到apple_callback_data如果apple_callback_data的status是21007,說明是沙盒模式(不用花錢就可以購買) 要根據具體需求判斷處理邏輯,需要注意的是,ios的審核在支付的時候就采用的沙盒模式。

 

如果apple_callback_data的status是0,就要從apple_callback_data[‘receipt’][‘in_app’]這個list中拿到所有的記錄,每一個進行充值。然后記錄transaction_id和original_transaction_id來防止同一個transaction被重復使用。

 

https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Restoring.html

 

https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1 => Original Transaction Identifier

返回所有充值成功和重復的transaction_id, 有client來complete transaction

 

總結

 

支付作為核心模塊,除了技術上的保證,商務也應該每周進行一次對賬。如果發現apple上的收入和服務端記錄的收入有比較大的差距,就應該抓緊查看原因。

 

最后給出一個apple_callback_data的例子

 

{

  "status": 0,

  "environment": "Production",

  "receipt": {

    "download_id": 75017873837267,

    "adam_id": 1149703708,

    "request_date": "2017-01-13 06:57:20 Etc/GMT",

    "app_item_id": 1149703708,

    "original_purchase_date_pst": "2016-11-17 18:57:09 America/Los_Angeles",

    "version_external_identifier": 820252187,

    "receipt_creation_date": "2017-01-13 05:04:52 Etc/GMT",

    "in_app": [

      {

        "is_trial_period": "false",

        "purchase_date_pst": "2017-01-12 21:04:52 America/Los_Angeles",

        "original_purchase_date_pst": "2017-01-12 21:04:52 America/Los_Angeles",

        "product_id": "com.lucky917.live.gold.1.555",

        "original_transaction_id": "350000191094279",

        "original_purchase_date": "2017-01-13 05:04:52 Etc/GMT",

        "original_purchase_date_ms": "1484283892000",

        "purchase_date": "2017-01-13 05:04:52 Etc/GMT",

        "purchase_date_ms": "1484283892000",

        "transaction_id": "350000191094279",

        "quantity": "1"

      }

    ],

    "original_purchase_date_ms": "1479437829000",

    "original_application_version": "26",

    "original_purchase_date": "2016-11-18 02:57:09 Etc/GMT",

    "request_date_ms": "1484290640800",

    "bundle_id": "com.lucky917.ios.Live",

    "receipt_creation_date_pst": "2017-01-12 21:04:52 America/Los_Angeles",

    "application_version": "32",

    "request_date_pst": "2017-01-12 22:57:20 America/Los_Angeles",

    "receipt_creation_date_ms": "1484283892000",

    "receipt_type": "Production"

  }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM