Защита против универсальных взломов in-app покупок

в 11:22, , рубрики: apple, heroku, in-app, iOS, ruby, разработка под iOS, метки: , , , ,

Не так давно шумели новости о активации in-app покупок бесплатно и даже без джейлбрейка. Идея проста, в систему устанавливаются ssl сертификаты и прописывается кастомный dns сервер, который запросы к серверам apple будет пересылать на сервер взломщиков. Сервер взломщиков будет подтверждать покупку и она успешно активируется на устройстве. После выхода этой новости паники было много и Apple даже пришлось что-то делать и рассказывать разработчикам, как защитить их приложение. На самом деле проблема была не нова, на джейлбрейкнутых устройствах уже давно можно было активировать in-app покупки бесплатно. Решение проблемы так же не ново, оно описано в документации Apple, но практической реализацией никто себя не утруждал. О моей версии такой защиты и пойдет речь ниже.

Как работают in-app покупки.

Есть два возможных сценария. Простой:
Защита против универсальных взломов in app покупок
Устройство активирует покупку через сервера apple без дополнительной валидации и участия сервера разработчика.

Сложный:
Защита против универсальных взломов in app покупок
Сервер разработчика может участвовать в процессе покупки следующим образом:

  • отправляет список возможных покупок (шаг 2),
  • валидирует чек покуки (шаги 10-11),
  • предоставляет доступ к какому-то дополнительному контенту (шаги 13-14).

Нас интересуют шаги 10-11, т.к. именно на них мы можем помочь устройству определить был чек выписан сервером apple или это подделка.

Тут надо добавить что исходники из статьи Apple могут помочь с валидацией чека прямо из приложения, но эта защита не отличается надежностью, т.к. никто не мешает перенаправить запросы к валидирующему серверу, на адрес сервера взломщиков, который будет возвращать ожидаемый ответ.

Валидация

Валидировать чек покупки мы можем только на сервере Apple. Для этого надо отправить JSON с чеком закодированным в base64, внутри HTTP POST запроса:

{
"receipt-data" : "(receipt bytes here)"
}

На один из серверов Apple,.

В ответ сервер вернет статус валидации, и если валидация успешна, декодированные поля чека.

{
"status" : 0,
"receipt" : { (receipt here) }
}

От теории к практике

Понимая описанную выше механику не составило труда написать приложение-прокси на ruby, которое пересылает запросы на валидацию на один из серверов Apple. Я выложил готовый к использованию код приложения на GitHub. Буду рад улучшениям и pull-запросам. Также его можно потрогать на heroku: https://receiptValidator.heroku.com/validate, используя тестовый чек из репозитория. С галочкой sandbox — можно посмотреть корректый ответ, а без неё — на код ошибки.

В приложении мы анализируем ответ нашего сервера и решаем стоит активировать встроенные функции или это подозрительный чек и его можно игнорировать. Если интересно в следующей статье я напишу о защите внутри приложения.

Сухой итог

  • Валидация покупок через свой сервер делает приложение «особенным» и универсальные ломалки, перестают работать.
  • Взломать приложение всё еще возможно, но для этого надо ломать именно наше приложение.
  • Если кто-то потратит время и взломает покупки — можно добавить дополнительное шифрование в общении с нашим сервером.
  • Бесплатно на heroku мы получаем удобный ruby хостинг и шифрование https.

P.S. немного бессовестного самопиара: эта защита была написана специально для Galileo Offline Maps и была успешно опробована в версии 2.2, которая появилась в AppStore вчера утром.

Автор: mOlind

* - обязательные к заполнению поля