Как обезопасить пароли базы данных в PHP? - PullRequest
382 голосов
/ 19 сентября 2008

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

Ответы [ 16 ]

223 голосов
/ 19 сентября 2008

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

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

98 голосов
/ 03 августа 2009

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

<files mypasswdfile>
order allow,deny
deny from all
</files>
41 голосов
/ 16 апреля 2012

Самый безопасный способ - вообще не использовать информацию, указанную в вашем 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"));
39 голосов
/ 19 сентября 2008

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

34 голосов
/ 19 сентября 2008

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

14 голосов
/ 24 декабря 2013

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

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

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

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

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

11 голосов
/ 19 сентября 2008

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

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

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

include("/outside-webroot/db_settings.php");  
mysql_connect("localhost", $db_user, $db_pass);  
unset ($db_user, $db_pass);  
7 голосов
/ 19 сентября 2008

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

7 голосов
/ 19 сентября 2008

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

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

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

Петр

5 голосов
/ 15 февраля 2017

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

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

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

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

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

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