У меня есть небольшое приложение PHP, хранящее данные в базе данных MySQL . В настоящее время имя пользователя / пароль жестко закодированы в PHP-коде. Ситуация, которая мне не очень нравится, например, поскольку код также доступен в репозитории.
Лучшая идея, которую я имею, – переместить данные из кода в файл конфигурации (исключенный из репозитория) и каким-то образом закодировать его, поэтому он не читается напрямую (обфускация). Есть ли лучший и простой способ решения проблемы?
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password'); if (!$link) { die('Could not connect: ' . mysql_error()); } mysql_select_db('mydb');
Область применения: Я хочу создать прочное, но также удобное в использовании решение. Я хочу разумную безопасность, но здесь я не имею конфиденциальных данных.
Примечание. Больше не рекомендуется использовать функции mysql_connect
, см. Вопрос «Переполнение стека». Почему я не должен использовать функции mysql_ в PHP? *. Я мог бы изменить пример кода, но поскольку некоторые комментарии относятся к этому, я этого не делал. Однако первоначальный характер вопроса остается в силе.
Самый простой способ, как вы сказали, – использовать файл конфигурации.
Многие фреймворки используют это ( Zend , CakePHP , Kohana и т. Д.), И это самый распространенный способ делать вещи (даже в среде, отличной от PHP, такой как ASP.NET с файлами web.config
). Это позволяет также копировать значения конфигурации из среды в среду, просто скопировав файлы для сайта, что является преимуществом, полагаясь на переменные среды установки сервера (которые могут быть быстро потеряны и забыты).
Вам не нужно беспокоиться о запутывании пароля, поскольку он не является всемирно доступным файлом, он, конечно же, не должен быть доступен через Интернет. Что я имею в виду, так это то, что вы либо a) сообщите веб-серверу, что он не служит вашему конфигурационному файлу ( IIS уже делает это с файлами web.config
и обслуживает статус HTTP 404.8 вместо содержимого) или b) перемещает его за пределы ваш веб-каталог. Если кто-то может видеть ваш файл конфигурации, это хуже, чем в исходном коде.
Также будет хорошей идеей иметь базовую (пустую / стандартную) версию файла конфигурации и разделить ее на среду, чтобы у вас мог быть другой файл конфигурации для платформ производства, разработки и тестирования.
Переменная окружения – наиболее распространенный способ разграничения между этими средами, что-то вроде приведенного ниже кода:
// Check if it's been set by the web server if (!empty($_ENV['ENVIRONMENT'])) { // Copy from web server to PHP constant define('ENVIRONMENT', $_ENV['ENVIRONMENT']); } if (!defined('ENVIRONMENT')) { // Default to development define('ENVIRONMENT', 'development'); } // Load in default configuration values require_once 'config.default.php'; // Load in the overridden configuration file for this environment require_once 'config.' . ENVIRONMENT . '.php';
Другим способом, который довольно распространен, является использование файла конфигурации XML и чтение только необходимых значений (сохранение кэшированной копии файла конфигурации в памяти). Это очень легко можно ограничить только загрузкой определенных значений, а не разрешать произвольное включение файлов PHP и, в целом, лучшее решение, на мой взгляд, но выше, чтобы вы начали в правильном направлении.
Вероятно, вы захотите, чтобы ваш VCS проигнорировал файл. С другой стороны, вам может понадобиться скелет файла или один с разумными значениями по умолчанию (последний, конечно, не относится к данным для входа), чтобы управлять версией. Общим способом борьбы с этим является наличие зарегистрированного файла конфигурации шаблона, и процедура установки копирует этот файл в место реального файла конфигурации, где он настроен. Это может быть ручной или автоматизированный процесс.
(В то время как несколько не связанный с основным вопросом, введение константы для вашей среды позволяет вам делать некоторые другие интересные вещи, такие как перенос на фальшивую почтовую реализацию вместо Live SMTP , но, конечно, это также можно сделать с конфигурационным файлом)
Одно довольно приятное решение, если вы находитесь в Apache, чтобы хранить информацию в конфигурации виртуального хоста
SetEnv MYSQL_USER "xx" SetEnv MYSQL_PASSWORD "y2wrg435yw8"
Данные можно легко получить с помощью $_ENV[]
для использования в коде.
Как отмечали другие, поместите его в отдельный файл конфигурации вне исходного управления (очевидно, это будет упомянуто в коде, который находится под контролем источника).
Также неплохо было бы назвать файл config.php, а не config.ini, если каталог случайно не отображается, что означает, что файл не будет загружен, а он ничего не вернет.
Если вы считаете, что способ 12factor ценен, они рекомендуют сохранять конфигурацию в среде.
Это дает дополнительное преимущество, позволяя вам писать точный код при тестировании или иным образом в непроизводственной среде. Если вы хотите (или нуждаетесь) изменить базу данных или что-то еще, вам не нужно изменять свой код – вы просто меняете переменные среды, и вам хорошо идти.
Я бы хотел сохранить только файл конфигурации примера в репозитории, например config.php.dist, и не ставить фактический файл config.php под управлением версии.
Хороший вопрос. Вы можете перенести наиболее чувствительные элементы (например, ключи / пароли) в качестве переменных среды, но тогда это просто отложит проблему до конфигурации вашего сервера (что, предположительно, также находится в репозитории).
Вы также можете попытаться избежать паролей для таких вещей, как база данных, уменьшив пароль и закрепив его за брандмауэром. Ни одно из них не является идеальным решением, но они – подходы, о которых я знаю.
Рекомендуется переместить пароль из кода в файл конфигурации, поэтому пароль не будет находиться в репозитории. Идея зашифровать его в файле конфигурации сомнительна, потому что тот, у кого есть файл конфигурации + PHP-код, который расшифровывает его, всегда может запускать код и получать пароль с четким текстом. Вероятно, было бы лучше сохранить пароль в файле конфигурации в виде обычного текста и подумать, как защитить файл конфигурации от несанкционированного доступа.
Я не вижу здесь всей этой проблемы. Если вы используете репозиторий, вам, вероятно, не нужны жесткие пароли и конфигурация. Вместо этого вы должны указать по умолчанию:
host: localhost user: root pass: root name: db
Если вы действительно хотите, чтобы вы могли использовать и анализировать файл .ini
но он, вероятно, будет очень медленным по сравнению с массивом, установленным в исходном коде, и на самом деле не имеет для меня такого смысла.
Помните: единственное, чему вы можете доверять, это ваш исходный код, если они могут его получить, вы все равно ввернуты.
Вы всегда можете создать конфигурационный файл ini с помощью функции parse_ini_file .