usuario - PHP y MySQL: ¿cómo evitar la contraseña en el código fuente?
recuperar contraseña con phpmailer (9)
Esta pregunta ya tiene una respuesta aquí:
- Cómo proteger contraseñas de bases de datos en PHP? 17 respuestas
Tengo una pequeña aplicación PHP que almacena datos en una MySQL datos MySQL . Actualmente el nombre de usuario / contraseña están codificados en el código PHP. Una situación que realmente no me gusta, por ejemplo, ya que el código también está disponible en un repositorio.
La mejor idea que tengo es mover los datos del código a un archivo de configuración (excluido del repositorio), y de alguna manera codificarlo, por lo que no es directamente legible (ofuscación). ¿Hay alguna forma mejor y más fácil de usar para resolver el problema?
$link = mysql_connect(''localhost'', ''mysql_user'', ''mysql_password'');
if (!$link) {
die(''Could not connect: '' . mysql_error());
}
mysql_select_db(''mydb'');
Alcance: Quiero establecer una solución robusta, pero también fácil de usar. Quiero seguridad razonable, pero no estoy tratando con datos altamente confidenciales aquí.
Observación: Ya no se recomienda el uso de las funciones de mysql_connect
, consulte la pregunta de Stack Overflow. ¿ Por qué no debería usar las funciones de mysql_ en PHP? *. Pude haber cambiado el ejemplo del código, pero dado que algunos comentarios se refieren a esto, no lo hice. Sin embargo, la naturaleza original de la pregunta sigue siendo válida.
Buena pregunta. Podrías mover las partes más sensibles (por ejemplo, claves / contraseñas) como variables de entorno, pero eso simplemente pospondría el problema a la configuración de tu servidor (que, presumiblemente, también está en un repositorio).
También podría tratar de evitar las contraseñas para cosas como la base de datos, al hacer que la contraseña sea menos segura y protegerla detrás de un firewall. Ninguno de estos son soluciones perfectas, pero son los enfoques que conozco.
Como otros han mencionado, colóquelo en un archivo de configuración separado fuera del control de la fuente (obviamente esto se mencionará en el código que está bajo el control de la fuente).
También es una buena idea nombrar el archivo config.php en lugar de config.ini en caso de que el directorio se exponga accidentalmente, lo que significa que el archivo no se descargará, sino que no devuelve nada.
Es una buena idea mover la contraseña del código a un archivo de configuración, para que la contraseña no esté en el repositorio. La idea de encriptarla en un archivo de configuración es cuestionable, porque el que tiene el archivo de configuración + código PHP que lo descifra siempre puede ejecutar el código y obtener una contraseña de texto claro. Probablemente sería mejor mantener la contraseña en un archivo de configuración como texto sin formato y pensar cómo proteger el archivo de configuración del acceso no autorizado.
La forma más fácil es, como dijiste, usar un archivo de configuración.
Muchos frameworks usan esto ( Zend , CakePHP , Kohana , etc.) y es la forma más común de hacer las cosas (incluso en un entorno que no es PHP, como ASP.NET con sus archivos web.config
). Esto también le permite copiar los valores de configuración de un entorno a otro simplemente copiando los archivos para el sitio, lo que es una ventaja sobre la dependencia de las variables de entorno de configuración del servidor (que pueden perderse y olvidarse muy rápidamente).
No debería tener que preocuparse por la ocultación de la contraseña, ya que no es un archivo accesible a nivel mundial, ciertamente no debe ser accesible desde la web. Lo que quiero decir con esto es que o bien a) le dices a tu servidor web que no sirva tu archivo de configuración ( IIS ya lo hace con los archivos web.config
y sirve un estado HTTP 404.8 en lugar de los contenidos) o b) lo mueve fuera de su directorio web servido Si alguien puede ver su archivo de configuración, es peor que tenerlo en su código fuente.
También será una buena idea tener una versión base (vacía / predeterminada) del archivo de configuración y separarla por entornos, para que pueda tener un archivo de configuración diferente para las plataformas de producción, desarrollo y prueba.
Una variable de entorno es la forma más común de diferenciar entre estos entornos, algo así como el siguiente código:
// 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'';
Otra forma que es bastante común es usar un archivo de configuración XML y solo leer los valores que necesita según corresponda (almacenar una copia en caché del archivo de configuración en la memoria). Esto puede limitarse muy fácilmente a la carga solo en ciertos valores, en lugar de permitir la inclusión arbitraria de archivos PHP y, en general, es una mejor solución en mi opinión, pero lo anterior debería ayudarlo a comenzar en la dirección correcta.
Es probable que desee que su VCS ignore el archivo. Por otro lado, es posible que desee un esqueleto del archivo, o uno con valores predeterminados razonables (este último no se aplica a los datos de inicio de sesión, por supuesto), para ser controlado por la versión. Una forma común de lidiar con eso es tener un archivo de configuración de plantilla registrado, y el procedimiento de instalación copia ese archivo a la ubicación del archivo de configuración real, donde se personaliza. Esto puede ser un proceso manual o automatizado.
(Aunque no tiene nada que ver con la pregunta principal, introducir una constante para su entorno le permite hacer otras cosas interesantes, como posponer la implementación de correo falso en lugar de SMTP , pero por supuesto, esto también podría hacerse con un archivo de configuración)
Lo que haría es almacenar solo un archivo de configuración de ejemplo en el repositorio, como config.php.dist y no poner el config.php actual bajo control de versión.
No veo todo este problema aquí. Si está compartiendo un repositorio, probablemente no quiera codificar las contraseñas y la configuración. En su lugar, debe proporcionar los valores predeterminados uno:
host: localhost
user: root
pass: root
name: db
Si realmente lo deseas, puedes usar y analizar un archivo .ini
, pero es probable que sea muy lento en comparación con una matriz que se establece en el código fuente y realmente no tiene mucho sentido para mí.
Recuerda: lo único en lo que puedes confiar es en tu código fuente, si pueden conseguirlo, estás jodido de todos modos.
Si considera que la forma de 12factores es valiosa, recomiendan almacenar la configuración en el entorno.
Esto tiene la ventaja adicional de permitirle escribir exactamente el mismo código cuando está probando o en otro entorno que no sea de producción. Si desea (o necesita) cambiar la base de datos, o cualquier otra cosa, no hay necesidad de modificar su código; solo cambia las variables de entorno y está listo para continuar.
Siempre puede crear un archivo ini de configuración utilizando la función parse_ini_file .
Una solución muy buena, si está en Apache, es almacenar la información en la configuración de virtualhost
SetEnv MYSQL_USER "xx"
SetEnv MYSQL_PASSWORD "y2wrg435yw8"
Los datos se pueden obtener fácilmente usando $_ENV[]
para usar en el código.