¿Guardar la contraseña de acceso a la base de datos en la clase PHP const?

3

Tengo un proyecto PHP y necesito almacenar información de acceso a MySQL.

Tengo un archivo config.php fuera del directorio público y en el archivo que tengo:

class Config
{
    const host = "dbserver";
    const name = "dbname";
    const user = "dbuser";
    const pass = "dbpass";
}

Luego, en init.php (también fuera del directorio público) tengo funciones de ayuda y otras cosas:

include "config.php";
$db = MySQLWrapper(Config::host, Config::name, Config::user, Config::pass);
//... init sessions, spl_autoloads, class maps and other stuff

Ahora en el directorio público de www, tengo index.php:

require_once "full path to init.php"
create page

¿Es este un diseño bueno y seguro? ¿O hay algún problema con la clase const?

No quiero usar directamente las variables o la matriz, porque si alguien accidentalmente permite registros de errores en el servidor, las contraseñas en las variables podrían filtrarse en el registro de errores a través de la impresión de depuración de las variables.

    
pregunta Martin Mickey 14.12.2018 - 10:30
fuente

2 respuestas

0

Para mí, la forma en que se almacenan las credenciales no es tan importante como la forma en que se llaman.

Tenerlos en la lista justo en los parámetros de función / método los hará aparecer en el seguimiento de la pila de PHP normal:

$db = MySQLWrapper(Config::host, Config::name, Config::user, Config::pass);

function MySQLWrapper($host, $name, $user, $password){
    new PDO("nonexistent", $user, $password);
}

revelará las credenciales en la salida

Fatal error: Uncaught PDOException: invalid data source name in /in/iLFHa:13 
Stack trace: 
#0 /in/GaEGR(13): PDO->__construct('nonexistent', 'dbuser', 'dbpass')
#1 /in/GaEGR(10): MySQLWrapper('dbserver', 'dbname', 'dbuser', 'dbpass')

Entonces, para evitar eso, generalmente sugiero dos cosas:

  • para evitar que se muestren las variables desde el constructor de PDO, captura la excepción y vuelve a tirar a , por lo que contendría solo el mensaje pero no el seguimiento de la pila
  • para evitar que se muestren variables a partir de los parámetros de función / método, envíelos como variable compuesta: un objeto o una matriz.

Por lo tanto, independientemente de la fuente de las variables, sugeriría enviarlas como una matriz, no variables separadas (es una mala práctica en general, aquí es una compensación con seguridad) y detectar y volver a lanzar el error de conexión PDO:

$db = MySQLWrapper([
    'host' => Config::host,
    'name' => Config::name,
    'user' => Config::user,
    'pass' => Config::pass,
]);

function MySQLWrapper($config) {
    try {
        new PDO("nonexistent", $config['user'], $config['pass']);
    } catch (\PDOException $e) {
        throw new \PDOException($e->getMessage(), (int)$e->getCode());
    }    
}

Ahora es solo el mensaje de error y una pista donde ocurrió:

Fatal error: Uncaught PDOException: invalid data source name in /in/c9kpM:16 
Stack trace: 
#0 /in/c9kpM(10): MySQLWrapper(Array) 
#1 {main} thrown in /in/c9kpM on line 16
    
respondido por el Your Common Sense 14.12.2018 - 13:12
fuente
4

El primer paso es nunca almacenar la contraseña en webroot. Ya lo tienes cubierto. ¡Bien!

El segundo paso es no almacenar la contraseña en el código PHP. Su código base debe estar libre de secretos, ya sea en constantes de clase o cualquier otra cosa. Eso le permite comprometerse con el control de versiones, hacer copias de seguridad, compartirlas, etc., sin pensarlo dos veces.

Mantener los secretos fuera del código fuente no solo es bueno para la seguridad, sino también una buena práctica de desarrollo de software. Su fuente no debe depender del entorno en el que la aplicación la está ejecutando.

Entonces, ¿cómo resuelves esto? Considere utilizar una variable de entorno , una archivo de configuración o php_value in httpd.conf . Para todos estos casos, tendrá que pensar qué procesos tienen acceso al valor y cómo restringirlo.

    
respondido por el Anders 14.12.2018 - 11:07
fuente

Lea otras preguntas en las etiquetas