Как обезопасить пароли базы данных в PHP?

359

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

  • 1
    Чтобы обеспечить полную безопасность, вам необходимо настроить ssl-соединение, иначе любой пользователь в вашей сети все равно сможет прослушать введенный вами пароль.
  • 1
    Вы имеете в виду пароли пользователей или пароль базы данных, используемые в строке подключения?
Показать ещё 1 комментарий
Теги:
database
security

17 ответов

209
Лучший ответ

Несколько человек неправильно понимают это как вопрос о том, как хранить пароли в базе данных. Это не правильно. Речь идет о том, как сохранить пароль, который позволяет получить в базу данных.

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

  • 7
    Благодарю. Если я правильно понимаю, файл php будет включать в себя файл конфигурации, позволяющий использовать пароль. Например, я создаю файл app1_db_cfg.php, в котором хранятся логин, pword и имя базы данных. Тогда моя страница application.php содержит app1_db_cfg.php, и я в деле!
  • 0
    да, я обычно делаю DEFINE ("DB_NAME", "mydb"); и т. д. также удобно определить все, что вы будете использовать на более чем странице, что вы можете изменить позже
Показать ещё 15 комментариев
94

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

<files mypasswdfile>
order allow,deny
deny from all
</files>
  • 3
    Спасибо, это именно то, что я искал.
  • 0
    Полезно, если это действительно безопасно, хотя кажется, что у входа в оболочку все равно будет доступ.
Показать ещё 5 комментариев
35

Самый безопасный способ - не иметь информацию, указанную в вашем PHP-коде вообще.

Если вы используете Apache, это означает, что вы должны установить данные о соединении в файле httpd.conf или файлах виртуальных хостов. Если вы это сделаете, вы можете вызвать mysql_connect() без параметров, что означает, что PHP никогда не будет выводить вашу информацию.

Вот как вы указываете эти значения в этих файлах:

php_value mysql.default.user      myusername
php_value mysql.default.password  mypassword
php_value mysql.default.host      server

Затем вы открываете соединение с mysql следующим образом:

<?php
$db = mysqli_connect();

Или вот так:

<?php
$db = mysqli_connect(ini_get("mysql.default.user"),
                     ini_get("mysql.default.password"),
                     ini_get("mysql.default.host"));
  • 1
    Пожалуйста, проверьте правильные значения ini_get («значения по умолчанию») php.net/manual/en/class.mysqli.php
  • 0
    Можно ли использовать это в их файле .htaccess?
Показать ещё 9 комментариев
35

Храните их в файле вне веб-корневого каталога.

  • 28
    А также, как упоминалось в другом месте, за пределами контроля источника.
  • 4
    мы сможем включить это? например, в PHP мы можем тогда include('../otherDirectory/configfile.conf') ?
Показать ещё 1 комментарий
34

Для чрезвычайно безопасных систем мы шифруем пароль базы данных в файле конфигурации (который сам защищен системным администратором). При запуске приложения/сервера приложение затем запрашивает системный администратор для ключа дешифрования. Затем пароль базы данных считывается из файла конфигурации, дешифруется и сохраняется в памяти для будущего использования. Все еще не на 100% безопаснее, так как он хранится в дешифрованной памяти, но вы должны называть его "достаточно безопасным" в какой-то момент!

  • 83
    что если админ умрет?
  • 31
    @RaduMurzea это смешно. Когда вы слышали о смерти Sys Admins? Они как Макдональдс, они просто появляются / исчезают из ниоткуда!
Показать ещё 6 комментариев
13

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

  • Создайте пользователя ОС для своего приложения. См. http://en.wikipedia.org/wiki/Principle_of_least_privilege
  • Создайте переменную среды (несезонной) ОС для этого пользователя с паролем
  • Запустите приложение как пользователь

Преимущества:

  • Вы не будете проверять свои пароли в исходном контроле случайно, потому что вы не можете
  • Вы случайно не испортите права доступа к файлам. Ну, возможно, но это не повлияет на это.
  • Может быть прочитан только root или этим пользователем. Root может читать все ваши файлы и ключи шифрования в любом случае.
  • Если вы используете шифрование, как безопасно хранить ключ?
  • Работает x-платформа
  • Обязательно не передавать envvar в ненадежные дочерние процессы.

Этот метод предложен Хероку, который очень успешен.

11

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

mysql_connect("localhost", "me", "mypass");

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

include("/outside-webroot/db_settings.php");  
mysql_connect("localhost", $db_user, $db_pass);  
unset ($db_user, $db_pass);  
  • 9
    Если у кого-то есть доступ к памяти, вы все равно облажались. Это бессмысленная фальшивая безопасность. За пределами webroot (или, по крайней мере, защищенный .htaccess, если у вас нет доступа выше вашего webroot), это единственный безопасный вариант.
  • 2
    @uliwitness - Это все равно, что сказать, что если кто-то может взломать замок вашего сетевого операционного центра с помощью ацетиленовой горелки, это означает, что дверь также является поддельной защитой. Хранение конфиденциальной информации, связанной с самой узкой областью, всегда имеет смысл.
Показать ещё 1 комментарий
7

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

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

  • Не используйте комбинацию имени пользователя и пароля для чего-либо еще.
  • Настройте сервер базы данных только для приема соединений с веб-узла для этого пользователя (локальный хост еще лучше, если БД находится на одном компьютере). Таким образом, даже если учетные данные отображаются, они никому не нужны, если у них нет других доступ к машине.
  • Обфускайте пароль (даже ROT13 будет делать) он не будет много защищать, если кто-то получит доступ к файлу, но, по крайней мере, это предотвратит его случайный просмотр.

Питер

5

Я думаю, что OP означает пароль базы данных.

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

5

Если вы используете PostgreSQL, он автоматически заглядывает в ~/.pgpass для паролей. Подробнее см. руководство.

5

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

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

4

Раньше мы сохраняли DB пользователя /pass в файле конфигурации, но с тех пор попадали в параноидальный режим - применяя политику защиты в глубину.

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

Мы переключились на сохранение пользователя/пароля в переменных среды, установленных в Apache VirtualHost. Эта конфигурация доступна только для чтения root - надеюсь, ваш пользователь Apache не работает как root.

Кон таким образом, что теперь пароль находится в глобальной переменной PHP.

Чтобы смягчить этот риск, мы соблюдаем следующие меры предосторожности:

  • Пароль зашифрован. Мы расширяем класс PDO, чтобы включить логику для дешифрования пароля. Если кто-то читает код, где мы устанавливаем соединение, не будет очевидно, что соединение устанавливается с зашифрованным паролем, а не с самим паролем.
  • Зашифрованный пароль перемещается из глобальных переменных в закрытую переменную. Приложение делает это немедленно, чтобы уменьшить окно, доступное в глобальном пространстве.
  • phpinfo() отключен. PHPInfo - это легкая цель получить обзор всего, включая переменные среды.
4

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

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

  • 1
    К сожалению, PHP-файл конфигурации может быть прочитан phpinfo (), и если кто-то оставит какой-нибудь тестовый скрипт позади, удачливый злоумышленник сможет прочитать пароль. Вероятно, лучше оставить пароль подключения в файле за пределами корневого каталога веб-сервера. Тогда единственный способ получить к нему доступ - либо с помощью оболочки, либо путем выполнения произвольного кода, но в этом случае вся безопасность теряется в любом случае.
3

Мы решили это следующим образом:

  • Использование memcache на сервере с открытым подключением с другого сервера паролей.
  • Сохранить в memcache пароль (или даже весь файл password.php зашифрованный) плюс ключ дешифрования.
  • Веб-сайт вызывает ключ memcache, содержащий парольную фразу парольного файла и дешифрует в памяти все пароли.
  • Сервер паролей отправляет новый зашифрованный файл паролей каждые 5 минут.
  • Если вы используете зашифрованный пароль .php в своем проекте, вы отправляете аудит, проверяющий, был ли этот файл затронут внешне - или просмотрен. Когда это произойдет, вы автоматически сможете очистить память, а также закрыть сервер для доступа.
3

Лучший способ - не хранить пароль вообще!
Например, если вы находитесь в системе Windows и подключаетесь к SQL Server, вы можете использовать встроенную аутентификацию для подключения к базе данных без пароля, используя текущий идентификатор процесса.

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

  • 3
    Нет смысла снова шифровать пароль. Кто-то, кто может получить незашифрованный пароль, может также получить любой пароль, необходимый для расшифровки пароля. Однако использование ACL & .htaccess - хорошая идея.
  • 2
    @uliwitness Я думаю, что вы, возможно, неправильно поняли - что вы подразумеваете под « снова зашифровывать»? Это всего лишь одно шифрование. И вы не хотите использовать парольные фразы (предназначенные для использования человеком) для его шифрования, достаточно сильное управление ключами, например, защищенное ОС, таким образом, что простой доступ к файловой системе не предоставит доступ к ключу.
Показать ещё 3 комментария
3

Дополнительный трюк заключается в использовании отдельного файла конфигурации PHP, который выглядит следующим образом:

<?php exit() ?>

[...]

Plain text data including password

Это не мешает вам правильно устанавливать правила доступа. Но в случае взлома вашего веб-сайта "require" или "include" просто выйдут из script в первой строке, поэтому еще труднее получить данные.

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

  • 0
    но тогда как скрипт php считывает учетные данные, хранящиеся в файле?
  • 2
    Вы используете fopen (), как для обычного текстового файла.
Показать ещё 2 комментария
3

Просто поместить его в конфигурационный файл где-то так, как обычно. Просто убедитесь, что вы:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню