PHP y MySQL: ¿cómo evitar la contraseña en el código fuente? [duplicate]

10 minutos de lectura

avatar de usuario
Horst Walter

Tengo una pequeña aplicación PHP que almacena datos en un mysql base de datos. Actualmente, el nombre de usuario y la contraseña están codificados en el código PHP. Una situación que no me gusta mucho, 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 codificarlos de alguna manera, para que no se puedan leer directamente (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 una seguridad razonable, pero no estoy tratando con datos altamente confidenciales aquí.

Observación: Ya no se recomienda utilizar el mysql_connect funciones, consulte la pregunta de desbordamiento de pila ¿Por qué no debería usar mysql_ funciones en PHP?*. Podría 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.

  • +1 por buena pregunta.

    – Yogesh Suthar

    26 de febrero de 2013 a las 12:21

  • 1) Use un archivo de configuración, 2) agregue config.php al archivo de ignorar del repositorio, 3) deje de usar mysql_* (tenía que ponerlo allí en alguna parte), ya que está en desuso

    – Amelia

    26 de febrero de 2013 a las 15:06

  • A partir de las 3, tienes razón. Acabo de agregar las 3 líneas de código como ejemplo para aclarar la pregunta y no presté la debida atención para usar la versión OO en su lugar.

    -Horst Walter

    26 de febrero de 2013 a las 16:01

  • Por favor, no uses mysql_* funciones en código nuevo. ya no se mantienen y están oficialmente en desuso. Ver el caja roja? Aprender acerca declaraciones preparadas en su lugar, y utilizar DOP o mysqliEste artículo le ayudará a decidir cuál. Si elige PDO, aquí hay un buen tutorial.

    – NullPoièteя

    26 de febrero de 2013 a las 18:53


avatar de usuario
Rudi Visser

La forma más fácil es, como dijiste, usar un archivo de configuración.

Muchos marcos usan esto (zend, pastelPHP, Kohanaetc) y es la forma más común de hacer las cosas (incluso en un entorno que no sea PHP como ASP.NET con su web.config archivos). Esto le permite también copiar los valores de configuración de un entorno a otro simplemente copiando los archivos para el sitio, lo cual es un beneficio en lugar de depender de las variables de entorno de configuración del servidor (que pueden perderse y olvidarse muy rápidamente).

No debería preocuparse por la ofuscación de la contraseña, ya que no es un archivo accesible para todo el mundo, ciertamente no debería ser accesible en la web. Lo que quiero decir con esto es que usted podría a) decirle a su servidor web que no entregue su archivo de configuración (IIS ya hace esto con web.config archivos y sirve un estado HTTP 404.8 en lugar del contenido) o b) Moverlo 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 separarlo por entornos, de modo 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 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 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 se puede restringir muy fácilmente para cargar solo 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.

Probablemente querrás tu VCS para ignorar 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 controlar la versión. Una forma común de lidiar con eso es tener un archivo de configuración de plantilla incorporado, y el procedimiento de instalación copia ese archivo en 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, la introducción de una constante para su entorno le permite hacer otras cosas interesantes, como posponer una implementación de correo falso en lugar de una implementación en vivo). SMTP uno, pero por supuesto esto también podría hacerse con un archivo de configuración)

  • Esta es una opinión pura, pero creo que debería expresarse aquí: personalmente creo que las constantes deben evitarse en favor de variables agradables e inyectables, evitando así el estado global. Por supuesto, también puede hacer esto con constantes, pero para evitar realmente el estado global, debe inyectarlas desde el alcance superior hacia abajo, lo que hace que las constantes no tengan sentido y las variables son (nuevamente, IMO) sintácticamente más agradables para los archivos de configuración.

    – DaveRandom

    26 de febrero de 2013 a las 12:46


  • @DaveRandom Siéntase libre de editar si cree que es apropiado proporcionar otro ejemplo/alternativa. Personalmente, siempre he preferido los archivos de configuración XML que se almacenan en caché, y no veo que la variable constante/entorno sea demasiado “malvada”, ya que es solo una y está controlada por el servidor host, en lugar de un cambio en el código por entorno . Todos los archivos de configuración en mi ejemplo se pueden implementar en paralelo, y el que se usa se elige según corresponda.

    –Rudi Visser

    26 de febrero de 2013 a las 12:49

  • Pequeña nota: he visto empresas que realmente dividen el código y la configuración. Esto significa que la configuración ni siquiera se encuentra en el directorio del proyecto; en cambio, está en algún lugar de /etc/ en el sistema de archivos de Linux. Esto podría ser útil para mantener sus contraseñas de producción un poco más seguras.

    – Sliq

    26 de febrero de 2013 a las 12:50

  • @RudiVisser No, lo que estaba diciendo era más un comentario general sobre constantes frente a variables y el uso de constantes en cualquier otra cosa que no sea el alcance superior que implica un estado global. No puedo encontrar fallas en su respuesta (tiene un +1), es solo mi opinión que no está directamente relacionada con la pregunta, pero pensé que valía la pena mencionarla con esta respuesta. En su ejemplo (definiendo un ENVIRONMENT) Probablemente estaría inyectando simulacros de desarrollo que implementan las mismas interfaces que sus contrapartes de producción pero con el comportamiento alternativo deseado en lugar de ensuciar el código con controles de entorno. YMMV.

    – DaveRandom

    26 de febrero de 2013 a las 12:56

  • @DaveRandom Veo completamente de dónde viene, sí, toda esta práctica se puede envolver en algo más agradable, pero como un concepto primordial sigo pensando que establecer el entorno constante en el servidor físico es un nivel bastante superior y una buena manera de obtener información sin un cambio de código! Tus comentarios también están algo relacionados, así que, como digo, si quieres editar alguna de estas notas, no dudes en hacerlo 🙂

    –Rudi Visser

    26/02/2013 a las 13:00

Una solución bastante buena, si está en Apache, almacena la información en la configuración del host virtual

SetEnv  MYSQL_USER     "xx"
SetEnv  MYSQL_PASSWORD "y2wrg435yw8"

Los datos se pueden recuperar fácilmente usando $_ENV[] para su uso en el código.

  • así es como lo hacen algunos hosts en la nube también

    – nurettina

    26 de febrero de 2013 a las 14:32

  • Sí, Adam Wiggins (cofundador de Heroku y CTO) menciona almacenar créditos en env. vars en la metodología de aplicación de 12 factores aquí: 12factor.net/config Sin embargo, eso no es específico de la configuración de vhost.

    – Gary S. Weaver

    26 de febrero de 2013 a las 16:02


  • $_ENV[‘MYSQL_USER’] no funcionó para mí, tuve que usar getenv(‘MYSQL_USER’) – php.net/manual/en/function.getenv.php

    – trabajo

    28/04/2014 a las 21:42

  • Tener el pase en el archivo de configuración fuera de la raíz es más seguro que exponerlo a getenv() que podría inyectarse y ejecutarse desde cualquier parte del sitio web.

    – Azul profundo

    22 de enero de 2017 a las 22:22

  • Solo asegúrese de que los usuarios no puedan acceder a los archivos de configuración del sitio.

    – frodeborli

    3 de julio de 2018 a las 9:24

avatar de usuario
agudosoftware

Como han mencionado otros, colóquelo en un archivo de configuración separado fuera del control de fuente (obviamente, esto se mencionará en el código que está bajo control de fuente).

También es una buena idea nombrar el archivo config.php más bien que config.ini en caso de que el directorio se exponga accidentalmente, lo que significa que el archivo no se descargará, sino que no devolverá nada.

  • +1 por la idea con config.php – bueno saber truco de todos modos

    -Horst Walter

    26 de febrero de 2013 a las 12:35

  • y/o mantener la configuración FUERA de DOCUMENT_ROOT y/o protegida específicamente por un archivo .htaccess o una configuración de servidor web. Personalmente, me gusta mantener esas configuraciones e incluir archivos FUERA de DOCUMENT_ROOT. Usando Apache Magic (mi término, no una pieza de software) puede ocultar un proyecto completo de Code Igniter sin exponer ningún archivo para que se descargue directamente.

    – Chronofish

    26 de febrero de 2013 a las 17:51

Si sientes que el factor 12 way es valioso, recomiendan almacenar la configuración en el entorno.

Esto tiene la ventaja añadida de permitirle escribir el exactamente el mismo código cuando está probando o en un entorno que no sea de producción. Si desea (o necesita) cambiar la base de datos, o cualquier otra cosa, no es necesario que modifique su código; simplemente cambie las variables de entorno y listo.

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 real bajo control de versión.

avatar de usuario
troelskn

Buena pregunta. Podría mover las piezas más sensibles (por ejemplo, claves/contraseñas) como variables de entorno, pero eso simplemente aplazaría el problema a la configuración de su servidor (que presumiblemente también está en un repositorio).

También puede intentar evitar las contraseñas para cosas como la base de datos, haciéndola menos contraseña y protegiéndola detrás de un firewall. Ninguna de estas son soluciones perfectas, pero son los enfoques que conozco.

avatar de usuario
Pedro Mortensen

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 cifrarlo en un archivo de configuración es cuestionable, porque quien tiene el archivo de configuración + el 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 en cómo proteger el archivo de configuración del acceso no autorizado.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad