Soy nuevo en PHP y espero que alguien me pueda ayudar con esto.

Me gustaría almacenar dos valores (un correo electrónico y una contraseña) en una base de datos MySQL usando PHP. La entrada se pasa a la página PHP a través de Ajax en jQuery (a través de un evento onclick en un sitio web).

Ahora quiero proteger este PHP consulta en contra de la inyección de SQL – estoy hablando de un sitio web estándar así que no quiero exagerar, pero creo que algunos estándar de protección no puede ser malo.

A continuación es lo que tenía antes para asegurarse de que el procedimiento general de trabajo es el que es.
Luego trató de aumentar la seguridad mediante el uso de de cifrado de contraseña y declaraciones, pero no estoy seguro si lo hice de la manera correcta + no sé si, y cómo esta debe ser aplicado a la parte Select (donde estoy comprobando si el email ya existe).

He visto un montón de páginas sobre este tema, pero como un principiante que es exactamente mi problema aquí.
¿Puede alguien decir con esto como un ejemplo de lo que debe ser cambiado o añadido aquí y tal vez ofrecer algunas explicaciones breves ? Me gustaría seguir usando MySQLi si es posible.

De edad PHP:

$conn = new mysqli($servername, $username, $password, $dbname);
$conn->set_charset("utf8");
if($conn->connect_error){
    die("Connection failed: " . $conn->connect_error);
}
$email = $_POST["email"];
$pw = $_POST["pw"]; 

$sql = "SELECT email FROM Users WHERE email = '" . $email . "'";
$query = $conn->query($sql);
if(mysqli_num_rows($query) > 0){
    echo "Record already exists";
}else{
    $sql = "INSERT INTO Users (email, pw) VALUES ('" . $email . "', '" . $pw . "')";
    if($conn->query($sql)){
        echo "Update successful";
    }else{
        echo "Update failed";
    };
}
$conn->close();

Nueva PHP:

$conn = new mysqli($servername, $username, $password, $dbname);
$conn->set_charset("utf8");
if($conn->connect_error){
    die("Connection failed: " . $conn->connect_error);
}
$email = $_POST["email"];
$pw = password_hash($_POST["pw"], PASSWORD_BCRYPT); 

$sql = "SELECT email FROM Users WHERE email = '" . $email . "'";
$query = $conn->query($sql);
if(mysqli_num_rows($query) > 0){
    echo "Record already exists";
}else{
    $sql = $conn->prepare("INSERT INTO Users (email, pw) VALUES ('" . $email . "', '" . $pw . "')");
    $sql->bind_param('s', $name);
    $sql->execute();
    $result = $sql->get_result();
    if($result){
        echo "Update successful";
    }else{
        echo "Update failed";
    };
}
$conn->close();

Actualización:

Después de la gran respuesta de Jite y los comentarios de otros aquí he modificado mi consulta como sigue – podría alguien quisiera saber si esto es correcto ahora según Jite sugerencias ?

$conn = new mysqli($servername, $username, $password, $dbname);
$conn->set_charset("utf8");
if($conn->connect_error){
    die("Connection failed: " . $conn->connect_error);
}
$email = $_POST["email"];
$pw = password_hash($_POST["pw"], PASSWORD_BCRYPT); 

$stmt = $conn->prepare("SELECT email FROM Users WHERE email = ?");
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result();
if(mysqli_num_rows($result) > 0){
    echo "Record already exists";
}else{
    $stmt = $conn->prepare("INSERT INTO Users (email, pw) VALUES (?, ?)");
    $stmt->bind_param('ss', $email, $pw);
    $stmt->execute();
    $result = $stmt->get_result();
    if($result){
        echo "Update successful";
    }else{
        echo "Update failed";
    };
}
$conn->close();

Muchas gracias de antemano,
Mike

Buscar en declaraciones preparadas: MySQLI php.net/manual/en/mysqli.prepare.php / DOP php.net/manual/en/pdo.prepared-statements.php
Gracias por esto – voy a echar un vistazo.
posibles duplicados de ¿Cómo puedo prevenir la inyección de SQL en PHP?
Gracias por este así – voy a echar un vistazo.

OriginalEl autor keewee279 | 2015-06-22

2 Comentarios

  1. 2

    En el Nuevo código PHP fragmento, siguen siendo vulnerables a las inyecciones.

    Usted está utilizando una instrucción preparada en la parte de inserción, pero no son en realidad el uso de los preparativos fortalezas correctamente.

    A la hora de crear una instrucción preparada, puede crear una consulta en la que usted agregue marcadores de posición en lugar de la prima de valores:

    $stmt = $conn->prepare("INSERT INTO Users (email, pw) VALUES (?, ?)");

    Los signos de interrogación son los marcadores de posición y luego son reemplazados por el uso de la bind_param método:

    $stmt->bind_param('ss', $email, $pw);

    La ss parte de la llamada de enlace le dice a la base de datos mysql que sus dos cadenas que se pasan a la base de datos (s para stringme para int etc).

    Va a enlazar una param ( $name ), pero no tiene ningún marcador de posición ni ningún tipo de referencia en la consulta..?

    La instrucción select en el otro lado sigue siendo inseguro y abierto a las vulnerabilidades.

    Probablemente voy a utilizar una instrucción preparada, al igual que con la parte de inserción.

    Siempre quiere asegurarse de que la entrada del usuario es «seguro» para la base de datos, si concat una cadena de consulta y agregar la entrada del usuario en la misma, la base de datos no va a escapar de las cadenas, se acaba de ejecutar.

    Sólo utilizan el estándar query método llama al escribir la consulta completa a sí mismo, sin ninguna entrada de parámetros, y especialmente no de entrada de parámetros que el usuario pasa!

    Muchas gracias por este y lo siento por la respuesta tardía. Esto es impresionante y las explicaciones aquí son realmente útiles ! Hay una manera que puedo enviar la consulta actualizada una vez completado el anterior ? Quiero asegurarme de que está bien, a continuación, ya que esta es la primera vez que escribo algo como esto.
    Se ve mucho mejor. Usted puede cambiar su mysqli_num_rows($result) el uso de la programación orientada a objetos mysqli estilo(que se puede utilizar en todos los otros códigos): $stmt->num_rows. Usted también podría lanzar en un regex cheque en el correo electrónico para validar (por lo que es en realidad una dirección de correo electrónico), pero lo que tenemos ahora debería funcionar (no corrió código, por lo que puede haber errores de sintaxis que no puedo ver en el fragmento de código, pero la idea general es correcta, jeje).
    No hay necesidad, la declaración ya saben sobre el resultado, así que todo lo que usted necesita hacer es comprobar el num_rows de la propiedad de la declaración de un objeto. Datos de javascript siempre puede ser modificado por el usuario, por eso es tan importante para validar todas las entradas en el lado del servidor (php). Ahora, la dirección de correo electrónico no será vulnerable, debido a las declaraciones preparadas, pero podría ser algo más que una dirección de correo electrónico.
    En lugar de comprobar $resultcompruebe si hay algún error en la instrucción: if($stmt->errno !== 0) { echo "Update failed: " . $stmt->error; } Debe mostrar el error.
    Bien, usted no TIENE que validar de nuevo, pero sería bueno hacer si desea asegurarse de que realmente es una dirección de correo electrónico, como podría haber sido manipulado por el usuario.

    OriginalEl autor Jite

  2. 1
    $query = $mysqli->prepare("INSERT INTO `table` (`col1`, `col2`) VALUES (?, ?)");
    $col1 = 100;
    $col2 = 14;
    $query->bind_param('ii', $col1, $col2);
    $query->execute();
    $query->close();
    Gracias por esto, y lo siento por la respuesta tardía !

    OriginalEl autor Abdullah Al Shakib

Dejar respuesta

Please enter your comment!
Please enter your name here