Является ли затенение / запутывание публичных идентификаторов базы данных действительно «лучшей практикой»?

23

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

РЕДАКТИРОВАТЬ : Конечно, теперь, когда я спрашиваю это, я нахожу некоторые ресурсы по этому вопросу:

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


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

Есть ли в этом какая-то правда, это просто паранойя, или это просто фальшивка?

Я могу придумать способы сделать это, но, конечно, это добавляет много сложности в код приложения. При каких обстоятельствах это будет полезно? Если это часто делают, как это обычно развертывается то , что люди? Хеширование идентификаторов? Что-то другое? Похоже, много работы для дополнительной безопасности. Я не ищу реальных решений, я просто хочу понять, как / почему люди делают это в реальном мире.

Это действительно считается «наилучшей практикой» или это просто микрооптимизация с малой ценностью?

ПРИМЕЧАНИЕ . Я думаю, что некоторые люди могли ошибиться: я не предполагаю, что трудно угадываемые идентификаторы были бы единственным механизмом безопасности, очевидно, были бы обычные проверки доступа. Давайте предположим, что они есть, и что простого знания идентификатора или хешированного идентификатора записи недостаточно для предоставления доступа.

Уэсли Мерч
источник

Ответы:

28

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

Например, если вы должны были выставить идентификатор заказа, который был сгенерирован последовательно, и у вас была атака социальной инженерии, когда кто-то позвонил в службу поддержки и сказал: «Эй, я просто потратил 2000 долларов на новый компьютер, а вы, ребята, прислали мне заказ другого парня на кабель за 15 долларов, теперь у меня нет 2000 долларов - вы можете потратить много времени, пытаясь проверить проблему, прежде чем либо решите, что она фальшивая, либо отправите фейкеру новый компьютер.

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

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

Я бы сказал, что называть это запутывание «наилучшей практикой» было бы натяжкой, но в некоторых сценариях это может уменьшить простоту использования другого недостатка в вашем коде проверки или авторизации. С другой стороны, не имеет значения, знает ли кто-нибудь, что вы написали пост в блоге № 1 или № 2559. Если идентификатор не является ценной информацией, даже с дополнительными знаниями, то аргумент, что его запутывание является наилучшей практикой, имеет меньший вес.

Есть второй потенциальный аргумент, который заключается в том, что идентификатор вашей базы данных может привести вас к конкретной реализации (или экземпляру) базы данных, и когда ваша компания будет выкуплена или выберет конкурента, и теперь вам нужно объединить две устаревшие системы или генерального директора. пьет с представителем из DynoCoreBase, и они решают, что теперь вы переместите все свои данные в DynoCoreBase версии 13h, и он хочет, чтобы все первичные ключи были направляющими, и вам нужно создать какой-то слой отображения, чтобы перевести старые идентификаторы в новые Идентификаторы, чтобы старые URL-адреса не ломались, но значение этих сценариев для вас зависит в большей степени от характера вашего бизнеса (и участия клиентов с этими идентификаторами), чем от какой-либо общей передовой практики.

JasonTrue
источник
2
Я чувствую, что вы единственный, кто понял мой вопрос. Как вы говорите, это определенно может «уменьшить легкость использования другой слабости», но какова эта ценность? Кто-нибудь решительно настроен на то, чтобы отстранить меня от соленого хэша? Я вроде думал, что это больше техника "профессионального преимущества", но я не вижу ее на практике (или, может быть, я не заметил бы, если бы я сделал ...). Как вы сказали, знание только идентификатора не должно предоставлять доступ (я думаю, что некоторые люди пропустили эту часть, я воспринимал это как должное). Так что, думаю, я согласен с вашей общей оценкой.
Уэсли Мёрч
9

Это мой взгляд на это:

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

Есть еще одна причина вне безопасности, о которой я могу подумать, чтобы реализовать это:

Конфиденциальность

Допустим, мы имеем дело с идентификаторами пользователей в URL. Если идентификатор пользователя Джо равен, 100а идентификатор пользователя Боба 101, вероятно, очевидно, что учетная запись Джо была создана первой. Хотя это может не иметь значения в большинстве приложений, это может иметь значение для некоторых. Это пример строгой конфиденциальности через неясность, поэтому, если у вас нет очень сложной системы запутывания идентификаторов пользователей, может быть достаточно легко распустить и выяснить, был ли пользователь с идентификатором 3Js9kW3hTs7sa120более длинным, чем пользователь с идентификатором Q8Hs73kks0hEg.

По ссылке, на которую я ссылался:

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

Использование идентификатора автоинкремента публично раскрывает количество объектов в базе данных и может показать, какие из них были созданы первыми, а какие новее. Эта информация может выдать тот факт, что бизнес является новым, или даже не очень хорошо. Например: скажем, вы заказываете книгу, и ваш идентификатор заказа 1. Может быть очевидно, что ваш заказ был первым в системе, что может расстраивать. Допустим, вы возвращаетесь и заказываете другой, и ваш идентификатор заказа 9. Это дает информацию о том, что только 7 заказов были размещены в сроки между вашими двумя заказами. Это может быть ценной информацией для конкурентов. В этом случае числовой идентификатор автоинкремента, вероятно, лучше запутывать.

Уэсли Мерч
источник
2

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

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

Просто слишком легко играть с числами в URL и получать доступ к другим записям.

Джеймс Андерсон
источник
1
Да, я имел в виду запутывание в названии и несколько других случаев - извините за это. Рад, что вы знаете, что я имел в виду. Я понимаю, что нужно «играть с числами», но это моя точка зрения: ваше приложение не должно быть защищено, делая идентификаторы немного сложнее угадывать и скрестив пальцы. Если кто-то приземляется /account/8hdy39s1lks062dfasd4и отображается на реальном счете, он не должен иметь доступа в любом случае.
Уэсли Мёрч
2

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

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

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

Конечно, чем больше слоев безопасности, тем лучше. Но один этот метод может быть более безопасным, чем пара учетных данных.

Andrea
источник
1
Я согласен. Какой бы метод защиты вы ни использовали, все сводится к отправке негагентных байтов по проводам. Если все сделано правильно, вы отправляете идентификатор, который так же хорош, как и зашифрованный, который не пропускает никакой информации о вашем пространстве идентификаторов, и я бы сказал, что это сильнее, чем то, о чем говорят люди, когда они панорамируют «безопасность через неизвестность». "
Марк Стобер
0

Здесь есть два аспекта: удобство использования и безопасность.

С точки зрения безопасности скрывать идентификаторы довольно бессмысленно; важно то, что идентификатор никогда не должен быть единственным «ключом» к любому непубличному ресурсу. Это означает, что если вы хотите предоставить выбранным пользователям доступ к определенной странице, просто недостаточно указать идентификатор страницы в URL-адресе, вам необходимо реализовать реальный механизм безопасности, такой как имя пользователя / пароль для входа или аутентификация с открытым / закрытым ключом, а также надлежащая авторизация (то есть система должна иметь возможность судить в каждом конкретном случае, разрешено ли пользователю X доступ к ресурсу Y, и действовать соответственно).

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

tdammers
источник
В веб-приложении я не могу представить примеры, когда люди по какой-либо причине записывали бы внутренний идентификатор. По электронной почте URL или что-то (или закладка), который имеет идентификатор, который я могу понять, но в этом случае я не вижу, где юзабилити вступает в игру. Я не предлагал менять их в середине потока, но я понимаю, как это может быть проблемой.
Уэсли Мёрч
@Madmartigan: это не так уж редко с пользовательскими информационными системами. Пользователи должны делать определенные вещи, и иногда приложение не совсем поддерживает их напрямую, или оно явно сломано, или, может быть, напрямую пройти через идентификаторы проще, чем идти по пути, предусмотренному архитекторами программного обеспечения. Люди могут получить очень творческие с этими вещами, и прежде чем вы знаете, эти «внутренние» ID начнёх ведут свою собственную жизнь.
tdammers
0

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

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

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

Килиан Фот
источник
2
Я думаю, что вы, возможно, ошиблись, я не предлагал «разрешить доступ к произвольным ресурсам, просто зная их внутренний идентификатор», я говорю о том, чтобы скрыть идентификатор поверх существующих мер безопасности. Очевидно, простое знание идентификатора или хэша не должно рассматриваться как авторизация.
Уэсли Мёрч
0

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

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

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

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

Генератор кода PHP
источник