Сегодня расскажу о том, как защитить in-app purchases в играх на мобильной платформе iOS с помощью собственного сервера. Практически все компании, которые выпускают свой продукт, заботятся о защищенности своих приложений и как можно больше пытаются защитить их от взлома. Одной из таких компаний является и та, в которой я работаю.
На данный момент на территории Испании проходит софтланч нашей игры. Сам я server-side developer и на мое плечо программиста легла проверка in-app purchases в игре, которую наша компания разрабатывала.
Все покупки в игре подтверждаются моим сервером. Происходит это следующим образом. Пользователь покупает в игре нашу валюту, тогда на смартфон от apple purchase server приходит json со всеми данными о покупке. После этого этот json попадает уже на наш сервер, сверяются некоторые поля и отправляются на apple verefication server, чтобы посмотреть, все ли хорошо. Если все в порядке, то от apple приходит json в котором есть много информации о покупке. Как утверждает документация на сайте Apple, нам достаточно проверить только поле status с присланного нам json. Если оно равно 0, то покупка правдивая и мы начисляем пользователю нашу валюту. Я ничего нового не придумывал и последовал этой документации.
В течение софтланча статистика нам показала, что один из пользователей купил нашей валюты в игре на 400 долларов. Однако мы не очень этому обрадовались, ведь видели, что эти покупки были с jailbreak смартфона. Посмотрев все данные, которые присылал девайс юзера нам на сервер, мы обнаружили, что они одинаковы. Немного поискав в интернете, мы натолкнулись на такую ??штуку как LocallAPStore Cydia Tweak в jailbreak iOS. Работает она следующим образом. Когда пользователь делает in-app purchase в игре, то LocallAPStore перехватывает данные и заменяет на свои, и возвращает callback игре, что покупка выполнена, ну а дальше оно приходит нам на сервер, отправляется в Apple. Нам приходит от apple verefication server response status 0.
Поэтому чтобы не допустить этого прежде всего проверяйте поле original_transaction_id, оно является уникальным, если вы в своей базе данных найдете идентичное значение этого поля — то это фрод. Но этого иногда бывает недостаточно. Для полной проверки уже после того как вам придет response json от apple verefication server следует сверить поле bid с уже вашим bundle id, а также сверять поле product_id.
Надеюсь вам будет полезной эта информация. Жду от вас комментариев, пожеланий и замечаний.
На данный момент на территории Испании проходит софтланч нашей игры. Сам я server-side developer и на мое плечо программиста легла проверка in-app purchases в игре, которую наша компания разрабатывала.
Все покупки в игре подтверждаются моим сервером. Происходит это следующим образом. Пользователь покупает в игре нашу валюту, тогда на смартфон от apple purchase server приходит json со всеми данными о покупке. После этого этот json попадает уже на наш сервер, сверяются некоторые поля и отправляются на apple verefication server, чтобы посмотреть, все ли хорошо. Если все в порядке, то от apple приходит json в котором есть много информации о покупке. Как утверждает документация на сайте Apple, нам достаточно проверить только поле status с присланного нам json. Если оно равно 0, то покупка правдивая и мы начисляем пользователю нашу валюту. Я ничего нового не придумывал и последовал этой документации.
В течение софтланча статистика нам показала, что один из пользователей купил нашей валюты в игре на 400 долларов. Однако мы не очень этому обрадовались, ведь видели, что эти покупки были с jailbreak смартфона. Посмотрев все данные, которые присылал девайс юзера нам на сервер, мы обнаружили, что они одинаковы. Немного поискав в интернете, мы натолкнулись на такую ??штуку как LocallAPStore Cydia Tweak в jailbreak iOS. Работает она следующим образом. Когда пользователь делает in-app purchase в игре, то LocallAPStore перехватывает данные и заменяет на свои, и возвращает callback игре, что покупка выполнена, ну а дальше оно приходит нам на сервер, отправляется в Apple. Нам приходит от apple verefication server response status 0.
Поэтому чтобы не допустить этого прежде всего проверяйте поле original_transaction_id, оно является уникальным, если вы в своей базе данных найдете идентичное значение этого поля — то это фрод. Но этого иногда бывает недостаточно. Для полной проверки уже после того как вам придет response json от apple verefication server следует сверить поле bid с уже вашим bundle id, а также сверять поле product_id.
Надеюсь вам будет полезной эта информация. Жду от вас комментариев, пожеланий и замечаний.
sadsanta
Ничего подобного документация не утверждает. Задача сервера сводится к проверке, что рецепт был подписан самим эпплом, и возврату этого рецепта в json.
Вы никакой информации на сервер о принадлежности этого рецепта не передаёте. Откуда ему знать ваш это был рецепт или нет?
Естественно, проверка соответствия bundle_id лежит на вашей совести, как и всех остальных параметров.
Или просто у вас очень преданный пользователь и он совершил вторую покупку. Предыдущая покупка из рецепта никуда не исчезнет.
sadsanta
Под рецептом я имею ввиду receipt, конечно, который на самом деле никакой не рецепт, а вовсе даже квитанция, просто я привык его так называть :)
VGaldemar
Я согласен с вашим утверждением. Apple проверяет подписан ли ими receipt. Однако большинство разработчиков не учитывают тот факт, что нужно проверять другие поля и проверяют исключительно лишь поле status. Я написал это чтобы подчеркнуть другим разработчикам проверять и остальные поля, так как сам ранее не учитывал этот момент и следствием этого стало то, что в нашей игре могли купить нашу валюту с помощью ложных транзакций.
Мы тестировали на реальных in-app purchase в игре с одного и того же устройства, и поле original_transaction_id было всегда разное (оно уникальное).