Может ли локальное хранилище считаться безопасным? [закрыто]

161

Мне необходимо разработать веб-приложение, которое будет работать в автономном режиме в течение длительного времени. Для того, чтобы это было жизнеспособным, я не могу избежать сохранения конфиденциальных данных (личных данных, но не тех данных, которые вы бы сохраняли только в хэше) в локальном хранилище.

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

  • шифрование всего, что идет в локальное хранилище, с использованием крипто-библиотеки stanford javascript и AES-256
  • пароль пользователя является ключом шифрования и не хранится на устройстве
  • обслуживающий весь контент (когда он-лайн) с одного доверенного сервера через ssl
  • проверка всех данных, поступающих в и из локального хранилища на сервере, с помощью проекта owasp antisamy
  • в разделе сети appcache, не используя *, и вместо этого перечисляет только URI, необходимые для соединения с доверенным сервером
  • в общем, пытаясь применить рекомендации, предложенные в шпаргалке OWASP XSS

Я ценю, что дьявол часто в деталях, и знаю, что существует много скептицизма по поводу локального хранилища и безопасности на основе JavaScript в целом. Кто-нибудь может прокомментировать, есть ли:

  • фундаментальные недостатки в вышеупомянутом подходе?
  • какие-либо возможные решения для таких недостатков?
  • Есть ли лучший способ защитить локальное хранилище, когда приложение HTML 5 должно работать автономно в течение длительного времени?

Спасибо за любую помощь.

user1173706
источник
«Я принимаю, что это не рекомендуемая практика» - так ли это? Разве не наоборот, что он был создан на самом деле для этого?
Хакре
2
Чтобы уточнить, я имел в виду не рекомендованную практику хранения конфиденциальных данных в локальном хранилище.
user1173706
Как то, что вы не должны передавать конфиденциальные данные в больших сетях?
Хакре
@ user1173706 Почему приложение должно функционировать, должно работать в течение длительного времени в автономном режиме? Каковы пользователи? Какие браузеры вы должны поддерживать? Я, например, думаю, что это возможно, но мне нужно знать особенности вашего сценария.
Бенджамин Грюнбаум
@ Бенджамин, я обновил вопрос. Спасибо.
user1173706

Ответы:

74

WebCrypto

Проблемы криптографии в клиентском (браузерном) javascript подробно описаны ниже. Все эти проблемы, кроме одной, не относятся к API WebCrypto , который в настоящее время достаточно хорошо поддерживается .

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

В сторону: если вы используете Node.js, используйте встроенный криптографический API.

Нативная JavaScript-криптография (до WebCrypto)

Я предполагаю, что основной проблемой является кто-то с физическим доступом к компьютеру, который читает localStorageваш сайт, и вы хотите, чтобы криптография помогла предотвратить такой доступ.

Если у кого-то есть физический доступ, вы также открыты для других атак и хуже, чем чтение. К ним относятся (но не ограничиваются ими): клавиатурные шпионы, автономная модификация скриптов, локальная инъекция скриптов, отравление кэша браузера и перенаправления DNS. Эти атаки работают, только если пользователь использует компьютер после того, как он был взломан. Тем не менее, физический доступ в таком сценарии означает, что у вас есть большие проблемы.

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

Существуют библиотеки, которые реализуют желаемую функциональность, например Stanford Javascript Crypto Library . Хотя есть и слабые места (как указано в ссылке из ответа @ ircmaxell):

  1. Отсутствие энтропии / генерации случайных чисел;
  2. Отсутствие безопасного хранилища ключей, то есть закрытый ключ должен быть защищен паролем, если он хранится локально или хранится на сервере (что запрещает автономный доступ);
  3. Отсутствие безопасного стирания;
  4. Отсутствие временных характеристик.

Каждый из этих недостатков соответствует категории криптографического компромисса. Другими словами, хотя у вас может быть «crypto» по имени, оно будет намного ниже строгости, к которой вы стремитесь на практике.

При всем этом, актуарная оценка не так тривиальна, как «криптография Javascript слабая, не используйте ее». Это не одобрение, а строгое предостережение, и оно требует от вас полного понимания подверженности вышеперечисленным недостаткам, частоты и стоимости векторов, с которыми вы сталкиваетесь, и вашей способности к смягчению или страхованию на случай неудачи: Javascript crypto, in несмотря на свои слабые стороны, может снизить вашу подверженность, но только против воров с ограниченными техническими возможностями. Однако вы должны предположить, что криптография Javascript не имеет никакого значения для решительного и способного злоумышленника, который нацеливается на эту информацию. Некоторые сочли бы неправильным называть данные «зашифрованными», когда известно, что так много недостатков присуще реализации. Другими словами, Вы можете незначительно уменьшить свою техническую подверженность, но вы увеличиваете свою финансовую подверженность раскрытию. Разумеется, каждая ситуация индивидуальна - и анализ снижения технической подверженности финансовому риску нетривиален. Вот наглядная аналогия:Некоторые банки требуют слабых паролей , несмотря на свойственный риск, потому что их подверженность потерям из-за слабых паролей меньше, чем затраты конечных пользователей на поддержку надежных паролей.

🔥 Если вы прочитали последний абзац и подумали: «Какой-то парень в Интернете по имени Брайан говорит, что я могу использовать криптографию Javascript», не используйте криптографию Javascript.

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

Брайан М. Хант
источник
Есть дополнительная документация (цитаты), доступная для общей позиции «не использовать криптографию JavaScript», предоставленной Группой NCC с 2011 года: криптография JavaScript считается вредной (особенно из-за ловушки 22 загрузки инструмента для проверки загрузок… качества PRNG … И т. Д.)
amcgregor
58

Ну, основная предпосылка здесь: нет, это еще не безопасно.

По сути, вы не можете запустить криптографию в JavaScript: JavaScript Crypto считается вредным .

Проблема в том, что вы не можете надежно получить криптографический код в браузере, и даже если вы можете, JS не предназначен для того, чтобы вы могли безопасно его запускать. Таким образом, до тех пор, пока в браузерах не появится криптографический контейнер (который предоставляют Encrypted Media Extensions, но который сплачивается для целей DRM), это невозможно будет сделать безопасно.

Что касается «лучшего пути», то сейчас его нет. Ваша единственная альтернатива - хранить данные в виде простого текста и надеяться на лучшее. Или не храните информацию вообще. В любом случае.

Либо так, либо если вам нужна такая защита, и вам нужно локальное хранилище, создайте пользовательское приложение ...

ircmaxell
источник
8
Downvoter: можете ли вы дать лучший ответ? Я понимаю, что это довольно противоречивый вопрос, когда между специалистами по безопасности (и непрофессионалами) существуют значительные разногласия, поэтому стоит поделится альтернативной точкой зрения. Если вы не голосуете по другой причине, в таком случае, как я могу улучшить этот ответ?
ircmaxell
9
@ircmaxell не я, но я не согласен с этим ответом. «Проблема в том, что вы не можете надежно получить криптографический код в браузере, и даже если бы вы могли, JS не предназначен для того, чтобы вы могли безопасно его запускать». - Зачем? Что присущая проблема? Вы можете использовать библиотеку шифрования Stanford JavaScript и шифровать / дешифровать ее. Вы можете хешировать, и вы можете делать все безопасно. Я не вижу внутренней проблемы в автономном приложении в JS, выполняющем стандартную версию crpyto, во многом как в приложении, построенном на любом другом языке.
Бенджамин Грюнбаум
11
@BenjaminGruenbaum: проблема в том, что существует множество мест, где этот крипто-код должен взаимодействовать со сторонним кодом. Весь смысл этой статьи, на которую я ссылался, заключается в том, что вы не можете контролировать среду исполнения. Итак, вы устанавливаете Stanford Crypto lib. Что произойдет, если какой-нибудь плагин браузера перезапишет sjcl.encryptключ злоумышленника? В JS это возможно на 100%, и вы ничего не можете сделать, чтобы остановить это. И это основной момент. Нет никаких механизмов "безопасности", которые бы препятствовали другим JS делать неприятные вещи с вашими данными. И это проблема .
ircmaxell
13
@ircmaxell Если вы спите с собаками, вы не можете ожидать, что не проснетесь с блохами. Если пользователь устанавливает дополнение для вредоносного ПО, точно такое же, как и пользователь, устанавливающий вирус на свой компьютер, оно ничем не отличается от него. Ваша программа на Java или C может быть настолько безопасна, насколько это возможно, но как только злоумышленник сможет запустить испорченный код. Это не отличается для JS. Аддоны не просто волшебным образом появляются в браузере. Более того, не сохранение информации в зашифрованном виде никоим образом не поможет, если у пользователя есть вредоносная программа, поскольку она может просто захватить данные в реальном времени.
Бенджамин Грюнбаум
9
@BenjaminGruenbaum: не согласен. В обычном приложении вам нужно либо поставить под угрозу само приложение (чтобы прочитать области памяти), либо получить root-доступ к коробке (скомпрометировать ОС). В любом случае, вам нужно идти на компромисс с чем-то более глубоким, чем просто нормальное поведение. JS позволяет это в нормальном поведении. В чем проблема ...
ircmaxell
12

В качестве исследования этой темы у меня есть презентация под названием «Защита TodoMVC с помощью API веб-криптографии» ( видео , код ).

Он использует API веб-криптографии для хранения списка задач, зашифрованного в localStorage паролем, защищающим приложение и использующим ключ, полученный из пароля, для шифрования. Если вы забудете или потеряете пароль, восстановление не будет. ( Отказ от ответственности - это был POC, а не предназначенный для производственного использования. )

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

В конце концов, шифрование localStorage, вероятно, защищает данные только от злоумышленников, которые имеют доступ только для чтения к системе или ее резервным копиям. Он добавляет небольшую глубину защиты для OWASP Top 10 item A6-Sensitive Data Exposure и позволяет вам ответить «Сохраняется ли какая-либо из этих данных в виде открытого текста в долгосрочной перспективе?» правильно.

Кевин Хакансон
источник
3

Это действительно интересная статья здесь. Я рассматриваю возможность внедрения шифрования JS для обеспечения безопасности при использовании локального хранилища. Совершенно очевидно, что это обеспечит защиту только в том случае, если устройство украдено (и реализовано правильно). Он не обеспечит защиту от клавиатурных шпионов и т. Д. Однако это не проблема JS, поскольку угроза кейлоггера - это проблема всех приложений, независимо от платформы их выполнения (браузер, нативный). Что касается статьи «JavaScript, криптографически опасный», на которую есть ссылка в первом ответе, у меня есть одна критика; в нем говорится «Вы можете использовать SSL / TLS для решения этой проблемы, но это дорого и сложно». Я думаю, что это очень амбициозный иск (и, возможно, довольно предвзятый) Да, SSL имеет стоимость,

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

Пол С
источник
Исторически сложилось так, что при начальных переговорах по подключению были необычные затраты (механические, а не финансовые). До такой степени, что корпорации будут использовать выделенные устройства терминации SSL, что может стать финансово дорогостоящим, помимо затрат на выдачу сертификатов и обеспечение доверия. Сегодня многие из этих проблем были решены, такие как продление продолжительности сеанса, чтобы избежать первоначального рукопожатия при последующих запросах.
amcgregor
2

Недоступно для любой веб-страницы (правда), но легко доступно и легко редактируется с помощью инструментов разработчика, таких как chrome (ctl-shift-J). Следовательно, перед сохранением значения требуется пользовательская криптография.

Но если javascript необходимо расшифровать (проверить), тогда алгоритм дешифрования доступен и им можно манипулировать.

Javascript нужен полностью безопасный контейнер и возможность правильно реализовывать закрытые переменные и функции, доступные только интерпретатору js. Но это нарушает безопасность пользователей - поскольку данные отслеживания могут использоваться безнаказанно.

Следовательно, JavaScript никогда не будет полностью безопасным.

rockmo
источник
-29

Нет.

localStorage доступен для любой веб-страницы, и если у вас есть ключ, вы можете изменить любые данные, которые вы хотите.

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

hellol11
источник
19
Это не доступно для "любой веб-страницы". Он доступен только для страниц в текущем домене.
dtabuenc
@dtabuenc наоборот, я некоторое время назад сделал ручку, которая показывает вам каждую пару ключ / значение в вашем localStorage , без каких-либо взломов.
hellol11
3
Нет! Сожалею. Локальное хранилище изолированно для каждого домена. Код, работающий в одном домене, не может получить доступ к значениям, которые были сохранены в локальном хранилище другим доменом. Например, google.com хранит кучу вещей в локальном хранилище. Вы не сможете перечислить какие-либо ключи с google.com в своем примере пера.
dtabuenc
@dtabuenc проверил это, вы правы.
hellol11