苹果应用内支付(iOS IAP)的流程与经常使用攻击方式

1. 客户端直接verify苹果的receipt 若是verify成功 自行发放商品 html

2. 客户端将receipt传给server,由server进行验证并发放商品ios

 

 

 

按照安全性原则, 客户端的全部信息都是不可信的,并且支付是业务中的核心模块,因此应该选择第二种。安全

 

下面简要介绍下,第二种方式的简单流程。并发

 

1. 客户端支付成功,拿到receiptapp

2. 客户端将receipt传到服务端 ide

3. 服务端去apple验证receipt 若是验证成功 就发放receipt中的商品ui

 

 

 

支付安全性

 

做为支付,安全性是第一位的,下面简要分析一下经常使用的攻击手段。加密

 

一、劫持apple server攻击 => 经过dns污染,让客户端支付走到假的apple_server,并返回验证成功的response。 这个主要针对支付方式一 若是是支付方式二 就无效。code

二、重复验证攻击 => 一个receipt重复使用屡次server

三、跨app攻击 => 别的app的receipt用到咱们app中来

四、换价格攻击 => 低价商品代替高价商品

五、歧义攻击 => 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.

六、中间人攻击 => 伪造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"

  }

}

相关文章
相关标签/搜索