Я чрезмерный инженер, если я рассматриваю преднамеренное неправильное поведение пользователя?

12

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

Для пояснения я представляю простой сервис JSON RESTful, например:

GET /items - to retrieve list of user's items
PUT /items/id - to modify an item
POST /items - to add a new item

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

Аутентификация выполняется с помощью базовой аутентификации по SSL.

Я говорю об одном возможном «вредном» поведении, подобном этому:

Пользователь вводит URL-адрес GET в браузере (без причины, но ...). Браузер запрашивает базовую аутентификацию, обрабатывает ее и сохраняет аутентификацию для текущего сеанса просмотра. Не закрывая браузер, пользователь посещает вредоносный веб-сайт с вредоносным JavaScript- кодом CSRF / XSRF, который отправляет POST в наш сервис.

Приведенный выше сценарий крайне маловероятен, и я знаю, что с точки зрения бизнеса мне не стоит слишком беспокоиться. Но ради улучшения ситуации, думаете ли вы, что если имя пользователя и пароль требуются и для данных JSON POST, это поможет?

Или я должен вообще отказаться от Basic Auth, избавиться от GET и использовать только POST / PUT с информацией об авторизации в них? Поскольку информация, полученная через GET, также может быть конфиденциальной.

С другой стороны, считается ли использование пользовательских заголовков чистой реализацией REST? Я могу отбросить Basic Auth и использовать пользовательские заголовки. Таким образом, можно избежать, по крайней мере, CSRF-атаки из браузера, и приложения, использующие сервис, установят имя пользователя / пароль в пользовательском вереске. Плохо для такого подхода то, что теперь сервис нельзя использовать из браузера.

Солнечный
источник
3
Как и с моим ответом, я также хотел бы оставить это заявление, я думаю, что, вероятно, лучше было бы ответить на SO или Security
Джефф Лангемайер
1
Я думаю, что вы переключили PUT и POST, как определено в RFC 2616 ( tools.ietf.org/html/rfc2616#section-9.5 ).
Сванте

Ответы:

6

Чрезмерная инженерия? Не за что. Анти-XSRF меры являются необходимой частью любого безопасного веб-приложения или службы. Может быть, а может и нет, «крайне маловероятно», что кто-то решит атаковать вас, но это не делает ваше программное обеспечение менее небезопасным.

Системы, как правило, подвергаются атакам с использованием XSRF, и, хотя результаты не так сразу очевидны - очевидно, хуже, чем инъекции SQL или XSS, они достаточно плохие, чтобы поставить под угрозу все взаимодействующие с пользователем функции.

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

я должен избавиться от GET

Нет, запросы GET используются для запросов чтения, которые не имеют активной операции записи (они являются «идемпотентными»). Это только операции записи, которые требуют защиты XSRF.

bobince
источник
Что если запрос GET может раскрыть конфиденциальную информацию?
Солнечно
@Sunny: Что вы рассматриваете конфиденциальные данные?
Крис
2
Крис, если я стану параноиком, все данные чувствительны, если они получены "неправильным" пользователем :). Это теоретическое.
Солнечно
Просьба просмотреть изменения в вопросе, который я добавил.
Солнечно
1
Это нормально, если ответ (GET или другой метод) содержит данные, которые должен видеть только пользователь. Атака XSRF только позволяет злоумышленнику сделать так, чтобы пользователь сделал определенный запрос, но не позволяет ему прочитать ответ, который возвращается от этого запроса. Если целевой скрипт не создан особым образом, чтобы сторонние страницы могли читать его из <script>тега, намеренно («JSONP») или случайно ( незащищенный JSON ).
Бобинц
32

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

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

Джаррод Крапива
источник
4
YAY для паранойи! У тебя есть враги! (И +1 для каждого запроса - атака )
Треб
0

Если код установлен и поддерживается, крайние случаи должны рассматриваться и рассматриваться в каждом конкретном случае.

Исправление из-за некоторых ошибок на моей части:

GET должен все еще использоваться как часть надлежащего сервиса RESTful, аутентификация должна все еще быть там в любом случае. Я пытался предположить, что в целях безопасности GET во многом похож на POST, но post выполняет свою работу, не помещая информацию в адресную строку, что, как правило, является большой разницей в безопасности (и почему мне не нравится GET), но как опубликовано @Lee,

GET requests are used to retrieve resources, and PUT/POST are used to add/update 
resources so it would be completely against expectations for a RESTful API to use
PUT/POST to get data. 

Поскольку это будет использоваться сторонними приложениями, следует следовать рекомендациям для службы RESTful, чтобы конечный разработчик не запутался в этой части.

Джефф Лангемайер
источник
3
Чем GET отличается от POST с точки зрения безопасности? Оба отправляются в виде обычного транспорта (HTTP или HTTPS), единственное отличие состоит в том, что строки запроса GET видны в адресной строке.
tdammers
1
@Sunny: POST так же уязвим, как и GET в этом отношении. Запустите telnet и поговорите с веб-сервером, если вы мне не верите.
tdammers
1
@Jeff: причина, по которой я поднимаю telnet (или curl, wget или старый добрый перехватчик), заключается в том, что он позволяет вам видеть весь поток данных. Да, HTTPS скрывает эту информацию от перехватчиков, но любой пользователь на любом конце SSL-соединения может видеть именно то, что видит telnet.
tdammers
1
@Jeremy: POST не показывает параметры в адресной строке, но, поскольку данные так же видимы в реальном HTTP-потоке, вы в целом правы.
tdammers
7
Запросы GET используются для извлечения ресурсов, а PUT / POST используются для добавления / обновления ресурсов, поэтому использование API-интерфейса PEST / POST для получения данных полностью противоречит ожиданиям API RESTful.
Ли
0

Вы должны учитывать все возможные варианты, включая то, что пользователь активно злонамерен и (успешно) восстанавливает любые барьеры «безопасность по неизвестности».

Но в то же время вы должны оценивать последствия успеха взлома и вероятность того, что попытка будет иметь место. Например:

  • Внутренняя служба, защищенная надежным межсетевым экраном, менее подвержена атаке, чем служба в общедоступном Интернете.

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


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

Стивен С
источник
Благодарю. Речь шла не о защите «от» пользователя, а о защите самого пользователя, если он действует безответственно. Но ваш ответ дает мало хороших замечаний.
Солнечно