Почему бы не использовать встроенных пользователей и разрешения MySQL для веб-сайта?

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

Кажется, есть пара общих тем:

  • «Не пытайтесь писать свои собственные сценарии шифрования, используйте существующую библиотеку (например, PHPass)».
  • «Не создавайте базы данных MySQL для каждого пользователя, создайте одну большую базу данных и напишите хороший PHP-скрипт для управления вашими пользователями, паролями и их данными».

Мне кажется, или эти двое не кажутся немного конфликтующими?

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

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

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

Так почему бы не создать пользователей MySQL для каждого пользователя сайта? Зачем запускать свой собственный PHP-скрипт для создания пользователей, а затем сохранять эту информацию в таблице базы данных, когда MySQL уже предлагает эту функциональность? Каковы настоящие причины? Думаем ли мы, что использование PHPass (или альтернативы) обеспечивает «более безопасное» хранилище паролей, чем встроенное в MySQL?

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

Если создание пользователя MySQL для каждого пользователя веб-сайта считается «приемлемым», то почему бы не создать новую базу данных или таблицу для каждого пользователя и не установить разрешения в MySQL, чтобы каждый пользователь мог получить доступ только к своим данным и ничего больше? Конечно, администратор с локальным доступом и паролем root может прочитать всю информацию.

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

///

Дополняющий вопрос.

Если это работает, то должен быть пользователь MySQL, чтобы PHP-скрипт мог использовать его для создания новых пользователей. Это будет хранить его пользователя / пароль в виде открытого текста, нет никакого способа обойти это?

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

Это возможно?


person James Drake    schedule 21.09.2013    source источник
comment
Вы можете создать пользователя mysql для каждого пользователя на вашем сайте. Но вам придется подключаться к mysql, постоянно используя разные учетные данные. Эти учетные данные должны где-то храниться. Возможно, в файле. Итак, у вас будет 2 копии данных: в таблице mysql.users и в вашем файле. ИМХО слишком много шума.   -  person user4035    schedule 21.09.2013
comment
Но когда пользователь входит на веб-сайт, он вводит пользователя и проходит, что просто используется непосредственно PHP для входа в MySQL. Таким образом, никакой пользователь/пароль не должен храниться где-либо.   -  person James Drake    schedule 21.09.2013
comment
А, да, я не подумал. Только одна проблема: виртуальные хостинги часто не позволяют создавать новых пользователей. Но в целом такой подход может работать.   -  person user4035    schedule 21.09.2013
comment
Говоря о выделенной машине, на которой работает один веб-сайт. Никакого общего хостинга, никаких общих баз данных MySQL, никакого общего ничего. Одна машина для одного приложения.   -  person James Drake    schedule 21.09.2013
comment
Веб-сайт обычно обращается к базе данных MySQL, когда к нему обращается анонимный пользователь: для получения меню, контента и т. д. Если вы реализуете пользователей как пользователей mysql, вам придется закрыть текущее соединение и повторно подключиться, используя учетные данные пользователя. Это не обязательно, при сохранении пользователей в собственной таблице и создает задержки. Кроме того, если вы хотите хранить дополнительную информацию о пользователях, такую ​​как имя, фамилия, должность и т. д., вам придется создать отдельную таблицу, связанную с таблицей mysql.users, а затем присоединиться к ним, поскольку вы не можете изменить основные таблицы mysql. Это также создаст трудности.   -  person user4035    schedule 21.09.2013
comment
Вы смешиваете Database User с Application User.   -  person Shiplu Mokaddim    schedule 21.09.2013
comment
Для этого примера не должно быть общедоступной информации. Поэтому, если анонимный пользователь просматривает сайт, он не видит ничего, кроме окна входа в систему (для отображения которого не требуется запрос к базе данных).   -  person James Drake    schedule 21.09.2013
comment
@shiplu.mokadd.im - но вопрос ПОЧЕМУ? Почему один пользователь MySQL для PHP-скрипта должен делать запросы (пользователь базы данных), а затем создавать множество пользователей для вашего веб-сайта с помощью PHP-скриптов (пользователи приложения)?   -  person James Drake    schedule 21.09.2013
comment
Я только что ответил на него.   -  person Shiplu Mokaddim    schedule 21.09.2013


Ответы (2)


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

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

Что касается хеширования паролей, используйте bcrypt через функцию PHP crypt(). Сохраните это в базе данных в таблице пользователей.

person SamT    schedule 21.09.2013
comment
Я получаю эти баллы за общее хранилище. Но если вся установка MySQL используется только для этого приложения, в чем разница между загрязнением базы данных/таблиц (где множество случайных новых пользователей создают множество баз данных/таблиц) и загрязнением строк (где множество случайных новых пользователей создают множество строк) ? Я действительно понимаю эти моменты, когда одна установка MySQL обслуживает разные базы данных для разных приложений. Но для создания этого единственного специализированного приложения кажется глупым писать целое PHP-приложение для обработки пользователей и их данных, а затем вставлять все это в одну таблицу или базу данных. - person James Drake; 21.09.2013
comment
Реляционные базы данных специально оптимизированы для работы с большим количеством строк, а не с таблицами и базами данных. Будут непредвиденные удары по производительности и, возможно, ошибки, которые возникнут из-за его использования таким образом. То, что вы пытаетесь сделать с MySQL, сродни использованию молотка, чтобы вбить шуруп в дерево. - person SamT; 21.09.2013

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

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

Или рассмотрим приложения, которые используются для связи между пользователями. Если пользователь А хочет отправить сообщение пользователю Б, ему нужно будет записать что-то в таблицу, которую сможет прочитать пользователь Б. Но если каждый пользователь имеет доступ только к своим таблицам, такой таблицы не существует. Что вы собираетесь делать, создавать базу данных для каждой пары пользователей? А как насчет многостороннего общения, вроде системы форумов?

person Barmar    schedule 21.09.2013
comment
Пользователь приложения и пользователь базы данных не совпадают. Пользователи приложений не являются пользователями базы данных. Само приложение является пользователем базы данных. Это главное - person Shiplu Mokaddim; 21.09.2013
comment
Я хотел бы дать каждому пользователю свою собственную таблицу или базу данных. - person James Drake; 21.09.2013
comment
@shiplu.mokadd.im Ну, в этом и смысл его вопроса: почему бы не использовать пользователей базы данных для реализации пользователей приложений? - person Barmar; 21.09.2013
comment
Пользователь не должен взаимодействовать с пользователем. На самом деле, с точки зрения безопасности я бы предпочел полное отсутствие взаимодействия между пользователями. Взаимодействие должно быть только между пользователем и администратором. - person James Drake; 21.09.2013
comment
Я получаю поиск вещь. Действительно ли это большая проблема — поиск по таблицам, а не по строкам? Я должен подумать, повлияет ли это на мое приложение. - person James Drake; 21.09.2013
comment
Как я уже сказал, это по-прежнему затрудняет написание общих приложений. Администратор должен использовать всю базу данных. - person Barmar; 21.09.2013
comment
Да, это большое дело. Вы не можете использовать индексы для поиска таблицы. - person Barmar; 21.09.2013
comment
Позвольте мне понять это последнее. Если бы я хотел искать всю информацию по «пользователю», я мог бы просто открыть базу данных с именем «пользователь», и у меня была бы вся его информация. Но если я хочу найти всех пользователей, у которых есть адрес в «городе», то это невозможно? Или просто очень хреново? - person James Drake; 21.09.2013