Статьи

Обеспечение безопасности гибридного мобильного приложения PhoneGap / Cordova

Автор Роба Лауэра

Без ведома многих разработчиков PhoneGap / Cordova ресурсы HTML / JavaScript / CSS, которые составляют ваше мобильное приложение, не компилируются и не запутываются иным образом при создании окончательного пакета приложения. В отличие от настоящих собственных битов приложения (т. Е. Инфраструктуры Cordova и пользовательских плагинов), которые скомпилированы в байт-код, основные ресурсы HTML5 существуют, как они поставляются, внутри пакета приложения.

Я напугал тебя? Надеюсь, что нет, поскольку существует множество способов лучше защитить ваше гибридное мобильное приложение, сохранить свои секреты в секрете и скрыть свою интеллектуальную собственность от посторонних глаз. Давайте начнем!

Храните свои секреты вне кода

Может быть, это здравый смысл, но это важный момент: если что-то не обязательно должно быть в кодовой базе вашего приложения, и вы не хотите, чтобы люди находили это, тогда не помещайте это в код. Относитесь к своему гибридному приложению так же, как к мобильному веб-сайту. Предположим худшее. Предположим, что люди собираются взломать приложение и изучить его содержимое, точно так же, как они могут щелкнуть правой кнопкой мыши, чтобы просмотреть исходный код сегодня.

СТРАТЕГИИ, ЧТОБЫ ХРАНИТЬ ЧУВСТВИТЕЛЬНЫЕ БИТЫ ИЗ НАШЕГО КОДА

Любая чувствительная бизнес-логика должна выполняться на сервере. Это правило номер один. Запустите свою логику на сервере и предоставьте результаты через API. Это может быть API, который вы пишете сами, например, в рамках  проекта ASP.NET Web API, или вы можете позволить Telerik сделать тяжелую работу за вас, используя  Telerik Backend Services . Backend Services позволяет вам создать безопасный бэкэнд для вашего приложения, которое живет в облаке и включает две функции, называемые «Cloud Code for Data» и «Cloud Functions»:

облачный код бэкэнд-сервисов telerik

Облачный код для данных  лучше всего описать как триггер в традиционной реляционной базе данных. Вы создаете функции в JavaScript, которые живут в облаке и выполняются всякий раз, когда запись данных создается, читается, обновляется или удаляется. Например, вы можете использовать облачный код для проверки запроса следующим образом:

Everlive.Events.beforeCreate(function (request, context, done) {
    var email = request.data.Email;
    var isValid = email && Everlive.Validation.validateEmail(email);
    //check whether the email is not null and whether it is valid
    if (!isValid) {
        Everlive.Response.setErrorResult('The "Email" field must be a valid email address.', 131, 500);
    }
    done();
});

Но варианты с облачным кодом для данных действительно бесконечны.

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

Защитите свой JavaScript

кто-то говорил

Если чувствительный код просто должен быть в вашем приложении, убедитесь, что вы защищаете свой JavaScript как можно лучше. По своей природе JavaScript не компилируется — поэтому лучшее, что мы можем сделать, — это запутать его до такой степени, чтобы он был настолько нечитаемым, насколько это возможно. Прежде чем отправить свое приложение в магазины приложений, минимизируйте свои активы JavaScript с помощью  Uglify . Или даже перейти на новый уровень с помощью платного сервиса, такого как  JScrambler , который выходит за рамки запутывания и обеспечивает более активную защиту ваших ресурсов JavaScript.

Обратите внимание, что в  Telerik AppBuilder вы можете указать, что некоторые файлы существуют только в конфигурациях отладки или выпуска. Поэтому, если вы тестируете приложение, используйте неинициализированные / запутанные ресурсы с *.debug.* синтаксисом, как в  myapp.debug.js. Аналогично, вы можете включить в *.release.* синтаксис более безопасные (минимизированные / запутанные) ресурсы , например,  myapp.release.js при публикации в магазинах приложений.

Вы можете не только управлять своими файлами отладки / выпуска в IDE AppBuilder, но и автоматизировать процесс, используя  CLI AppBuilder  и  GruntTJ VanToll  имеет  отличный пример  на использование этих инструментов для автоматизации минификации (с уродовать) и строит (с AppBuilder).

Загрузить JavaScript удаленно

Другая жизнеспособная стратегия — даже не включать ваши ресурсы JavaScript в ваше приложение, а загружать их удаленно при запуске приложения:

<script src="http://cordova.myapp.com/hello_world.js"></script>

Однако это не очень безопасно, так как быстрое сканирование вашего исходного кода покажет истинный источник. Лучшая реализация — загрузить удаленный JavaScript через безопасный API, который сначала аутентифицирует вашего пользователя:

$.ajax({
    type: "POST",
    url: "https://my-remote-endpoint.com/authenticate", // authenticate your user
    data: { username: username, password: password }, // use the authentication parameters that are best for you
    success: function (e) {
        // check for a successful authentication, and if so, load the script reference returned from your api
        $.getScript(e.scriptUrl);
    }
});

Вы можете дополнить это на стороне сервера, также убедившись, что только мобильные браузеры пытаются получить доступ к этому API. Хотя для кого-то ОЧЕНЬ легко подделать пользовательский агент, добавление дополнительной проверки на сервер не повредит. Например, в веб-API ASP.NET вы можете использовать следующие две строки кода, чтобы убедиться, что только веб-представления iOS / Android / WP8 обращаются к вашему API:

var userAgent = Request.Headers.UserAgent.ToString();
if (!userAgent.Contains("Mobile Safari") && !userAgent.Contains("IEMobile")) return;

Имейте в виду, что это вряд ли пригодно для будущего, так как новая версия IE (он же Spartan) называет  каждый браузер, кроме себя,  в строке пользовательского агента!

При необходимости обеспечьте безопасность всех вызовов API! В идеале ваше приложение будет запрашивать ключ с вашего сервера, как только пользователь успешно подтвердит свою подлинность. Затем этот ключ может быть передан обратно на каждый вызов API, который вы проверяете, проверяется на сервере и обрабатывается соответствующим образом. Масштабы того, что требуется для решения этой проблемы, не сложны, но из-за временных и пространственных ограничений я заставлю вас  взглянуть на этот пост,  который очень хорошо описывает процесс.

Безопасная передача данных

HTTPS

Речь идет не только о защите вашего JavaScript для защиты вашего IP, но и о безопасной передаче данных между вашим приложением и сервером. Как правило, все исходящие запросы должны обрабатываться через SSL / https — это не сложно!

Тем не менее, это не останавливаться на достигнутом. Чтобы предотвратить возможные атаки «человек посередине», используйте плагин Cordova, например  Secure HTTP,  для обеспечения истинного закрепления SSL.

Безопасное хранение данных

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

// save some data!
localStorage.setItem('key', 'value');

// get some data!
var myStuff = localStorage.getItem('key');

На iOS вы можете воспользоваться преимуществами безопасности, обеспечиваемой KeyChain, используя  плагин KeyChain  для шифрования данных в состоянии покоя на вашем устройстве:

// prepare some variables
var servicename = 'MY_PASSWORDS';
var key = 'TELERIK_PLATFORM_PASSWORD';
var value = 'LetMeIn!'; // fake of course 😀

// prepare the callback functions
function onSuccess (msg) {alert(msg)};
function onError (msg) {alert(msg)};

// store your password in the Keychain
new Keychain().setForKey(onSuccess, onError, key, servicename, value);

// get your password from the Keychain
new Keychain().getForKey(onSuccess, onError, key, servicename);

// remove your password from the Keychain
new Keychain().removeForKey(onSuccess, onError, key, servicename);

Finally, if you are using SQLite as an offline database, you may want to look at a solution such as SQLCipher to encrypt the database. Again, in this scenario, it may be worth considering using a backend data service such as Telerik Backend Services to ensure the security of your data at rest.

Keep Your App Out of the Hands of the Public

Telerik Appmanager

If you don’t want to risk your app being in the hands of anyone who might try to hack it, then use a service like Telerik AppManager to host your own private app store. This provides you with 100% control over who has the ability to install your app – and gives you the convenience of cross-platform app distribution for iOS, Android, and Windows Phone.

Limit Your Exposure

What else can you do to help secure your hybrid mobile apps? There are numerous other strategies you can use to help limit your exposure to security threats:

  1. Reduce the core Cordova plugins you use. In case of a zero day exploit of a Cordova plugin, it’s best to limit plugin access to only those your app really needs.

  2. Avoid Android 2.3 (Gingerbread) at all costs. Gingerbread is widely considered to be the most insecure version of Android and is no longer supported by Google. The easiest way to avoid Gingerbread is to set your minSdkVersion higher than 10 in your Android Manifest:

    <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="21" />
  3. Use the InAppBrowser for all external web sites. The InAppBrowserCordova plugin uses the device’s native browser security model and keeps the remote content separate from your app.

  4. Hide app content when switching between apps. Use thePrivacyScreen plugin to help your users hide app content when switching between apps on iOS or Android.

  5. Use iOS Touch ID. If you’re developing for iOS 8, you can provide users with a secure authentication mechanism by using the Touch ID cordova plugin.

Full App Encryption

все-в-все-безопасное

Last, but definitely not least, is the nuclear option. It is technically possible to modify Cordova to encrypt all of your HTML/CSS/JS assets as they are stored on the device, and then decrypt them at runtime. An oft-referenced tutorial to do so on iOS may be found here, but your mileage may vary.

Summary

When it comes to security, nothing is 100%. The goal is to get as close to that number as possible though. Start by limiting your exposure and putting as much sensitive data and logic on your (secured) server as possible. From there, work through the list provided and make sure you are doing your best to secure your hybrid mobile apps.