iOS應(yīng)用內(nèi)支付的那些坑
我們?cè)诮衲甏汗?jié)后上線了新的在線智能題庫:猿題庫。猿題庫現(xiàn)在推出了公務(wù)員考試行測(cè)和申論2個(gè)產(chǎn)品,均包括web, iOS和Android三個(gè)平臺(tái)。這次我們嘗試做一個(gè)收費(fèi)的產(chǎn)品,所以在iOS端集成了應(yīng)用內(nèi)支付(IAP)功能。在開發(fā)過程中和上線后,我們遇到了 IAP中的一些坑,在此分享給各位。
IAP 審核相關(guān)的坑
IAP開發(fā)的詳細(xì)步驟我寫在另一篇博客中了。在此主要介紹審核時(shí)遇到的問題。
IAP類型錯(cuò)誤
由于我們是按月付費(fèi)的產(chǎn)品,所以在設(shè)置IAP類型時(shí),我沒有經(jīng)驗(yàn),只是簡單設(shè)置成了可重復(fù)消費(fèi)(Consumable)的IAP項(xiàng)目。但是我不知 道,蘋果對(duì)于這種按時(shí)間收費(fèi)的產(chǎn)品,應(yīng)該使用不可更新的定閱(Non-Renewing Subscription)類型。這個(gè)類型設(shè)置錯(cuò)誤造成了我們app的一次審核被拒。
IAP驗(yàn)證邏輯
由于蘋果在iOS5.0以下有IAP的bug,使得攻擊者可以偽造支付成功的憑證。而iOS6.0的系統(tǒng)在越獄后同樣可以偽造憑證,所以我們對(duì)于應(yīng)用內(nèi)支付,增加了服務(wù)器端的驗(yàn)證。服務(wù)器端會(huì)將支付憑證發(fā)給蘋果的服務(wù)器進(jìn)行二次驗(yàn)證,以保證憑證是真實(shí)有效的。
在我們公司的測(cè)試服務(wù)器中,我們會(huì)連接蘋果的測(cè)試服務(wù)器(https://sandbox.itunes.apple.com/verifyReceipt)驗(yàn)證。
在我們部署在線上的正式服務(wù)器中,我們會(huì)連接蘋果的正式服務(wù)器(https://buy.itunes.apple.com/verifyReceipt )驗(yàn)證。
我們提交給蘋果審核的是正式版,我們以為蘋果審核時(shí),我們應(yīng)該連接蘋果的線上驗(yàn)證服務(wù)器來驗(yàn)證購買憑證。結(jié)果我理解錯(cuò)了,蘋果在審核App時(shí),只會(huì) 在sandbox環(huán)境購買,其產(chǎn)生的購買憑證,也只能連接蘋果的測(cè)試驗(yàn)證服務(wù)器。但是審核的app又是連接的我們的線上服務(wù)器。所以我們這邊的服務(wù)器無法 驗(yàn)證通過IAP購買,造成我們app的又一次審核被拒。
解決方法是判斷蘋果正式驗(yàn)證服務(wù)器的返回code,如果是21007,則再一次連接測(cè)試服務(wù)器進(jìn)行驗(yàn)證即可。蘋果的這一篇文檔上有對(duì)返回的code的詳細(xì)說明。
IAP上線后的遇到的情況
我們?cè)诜?wù)器端增加了驗(yàn)證IAP是否有效的邏輯。在產(chǎn)品上線后,如我們所料,我們收到了大量的欺騙性購買,這些都被我們的服務(wù)器識(shí)別出來了,但是我們也遇到了以下這次沒有想到的情況:
1、由于國內(nèi)越獄用戶的比例比較大(大概為50%),所以雖然我們服務(wù)器會(huì)驗(yàn)證購買憑證,但是每天有超過50%以上的憑證都是偽造的。同時(shí)由于蘋果 的驗(yàn)證服務(wù)器在美國,憑證驗(yàn)證請(qǐng)求響應(yīng)的時(shí)間比較慢,大量的偽造憑證發(fā)給蘋果服務(wù)器,不知道會(huì)不會(huì)被蘋果認(rèn)為我們是在惡意進(jìn)行DDOS。至少我們發(fā)現(xiàn)有些 時(shí)候,驗(yàn)證請(qǐng)求會(huì)超時(shí)。
2、由于國內(nèi)有許多小白用戶,他們的手機(jī)從購買時(shí)就被渠道商幫忙越獄過了并且安裝了IAP free插件。所以對(duì)于這類用戶,他們即使想付費(fèi)購買,由于系統(tǒng)原有的IAP支付功能已經(jīng)被破壞,所以他們是無法正常付費(fèi)的。麻煩的是,他們會(huì)以為這是我 們的app的問題,轉(zhuǎn)而給我們的客服打電話投訴。這讓我們非常郁悶。
3、蘋果的驗(yàn)證服務(wù)器有時(shí)候會(huì)出問題,我們發(fā)現(xiàn)本來約定好返回的JSON數(shù)據(jù)在有幾次返回的居然是一個(gè)XML格式的文件。造成我們將正常的付費(fèi) IAP憑證驗(yàn)證失敗。所以,在服務(wù)器記錄下所有的驗(yàn)證憑證非常有必要,一來可以防止黑客多次提交同一個(gè)成功憑證的重放攻擊,二來在需要時(shí)可以手工進(jìn)行再驗(yàn) 證。
越獄手機(jī)可能被黑客竊取購買憑證!
我們發(fā)現(xiàn)有一部分用戶反饋說已經(jīng)收到蘋果的扣費(fèi)賬單,但是我們從服務(wù)器的驗(yàn)證記錄看,他上傳的憑證卻是虛假的。由于這些用戶不太多,我們一開始以為 是用戶在惡意欺騙我們,后來我們讓他將蘋果的付費(fèi)賬單郵件轉(zhuǎn)發(fā)給我們,以及將itunes的購買記錄截圖轉(zhuǎn)發(fā)給我們,我們?cè)絹碓綉岩蛇@里面有一個(gè)黑色的產(chǎn) 業(yè)鏈。越獄手機(jī)的正常購買憑證可能被黑客的惡意程序截獲,具體的攻擊方式我們討論了一下,其實(shí)就是被中間人攻擊,詳細(xì)的過程如下:
1.越獄手機(jī)的在被破解后,可能從一些破解渠道安裝了黑客的惡意程序。
2.黑客將越獄手機(jī)所有https請(qǐng)求都經(jīng)過他的中間服務(wù)器。
3.當(dāng)有支付請(qǐng)求時(shí),黑客先將請(qǐng)求發(fā)給蘋果服務(wù)器,待蘋果將成功的憑證返回后,黑客將這個(gè)憑證替換成假的憑證,完全支付憑證的偷取。
或許有人會(huì)問,這個(gè)憑證拿來有什么用呢?很簡單 ,因?yàn)樘O果為了保護(hù)用戶的隱私,支付憑證中并不包含任何用戶的apple id信息,所以我們的app和服務(wù)器無法知道這個(gè)憑證是誰買的,而只能知道這個(gè)憑證是真的還是假的。于是黑客就可以用這個(gè)憑證,在另外的賬號(hào)中通知我們完 成了購買,而發(fā)來的驗(yàn)證憑證又是真實(shí)的,所以我們的服務(wù)器就會(huì)誤認(rèn)為是黑客的賬號(hào)完成了購買,繼而把會(huì)員期算在黑客的賬號(hào)上。
再舉一個(gè)簡單的例子,你拿500塊錢買了順風(fēng)優(yōu)選的500元購物券,由于這個(gè)購物券是不記名的,所以順風(fēng)優(yōu)選無法知道是誰買的。如果這個(gè)購物券在發(fā) 放過程中被人掉包,那么偷購物券的人就可以拿這個(gè)偷來的真購物券來購物,而順風(fēng)優(yōu)選的卡因?yàn)槭遣挥浢模砸矡o法查證這件事情。在這個(gè)例子中,購物券的 不記名和蘋果的支付憑證無賬號(hào)信息是同一個(gè)道理。
鑒于以上情況,考慮到越獄手機(jī)不但不能成功支付,還會(huì)有安全問題,所以我們?cè)谛掳嬷腥∠嗽姜z手機(jī)中的IAP支付功能。
所以,請(qǐng)大家還是不要越獄自己的手機(jī),iphone手機(jī)越獄后風(fēng)險(xiǎn)相當(dāng)大。實(shí)在不值得為了免費(fèi)玩幾個(gè)游戲就丟掉安全性。
【編者按】本文轉(zhuǎn)自猿題庫、粉筆網(wǎng)開發(fā)工程師唐巧的博客。