sql >> Base de Datos >  >> RDS >> Mysql

Disparadores PHP MySQL - ¿Cómo pasar variables para disparar?

Corrige esa inyección de SQL

$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$sql = "INSERT INTO table1 VALUES ('username','password'); 
// You must quote your $vars       ^        ^ ^        ^  like this
// or syntax errors will occur and the escaping will not work!. 

Tenga en cuenta que almacenar contraseñas sin cifrar en una base de datos es un pecado capital.
Consulte a continuación cómo solucionarlo.

Los disparadores no permiten parámetros
Solo puede acceder a los valores que acaba de insertar en la tabla.
El activador Insertar tiene una tabla ficticia new para esto.
El activador Eliminar tiene una tabla ficticia old para ver los valores que se van a eliminar.
El activador de actualización tiene tanto old y new .

Aparte de eso, no puede acceder a ningún dato externo.

DELIMITER $$    

//Creates trigger to insert into table1 ( logs ) the userid and patientid ( which has to come from php )    

CREATE    
TRIGGER ai_table1_each AFTER INSERT ON `baemer_emr`.`table1`    
FOR EACH ROW    
BEGIN    
  INSERT INTO table2 VALUES (NEW.idn, NEW.username, NEW.patientid);    
END$$    

La solución
Cree una tabla de agujero negro.
Las tablas de agujero negro no almacenan nada, su única razón de existir es con fines de replicación y para que pueda adjuntarles disparadores.

CREATE TABLE bh_newusers (
  username varchar(255) not null,
  password varchar(255) not null,
  idn integer not null,
  patient_id integer not null,
  user_id integer not null) ENGINE = BLACKHOLE;

A continuación, inserte datos en la tabla de agujero negro y procéselos con un disparador.

CREATE    
TRIGGER ai_bh_newuser_each AFTER INSERT ON `baemer_emr`.bh_newuser
FOR EACH ROW    
BEGIN    
  DECLARE newsalt INTEGER;
  SET newsalt = FLOOR(RAND()*999999);
  INSERT INTO users (username, salt, passhash) 
    VALUES (NEW.username, newsalt, SHA2(CONCAT(newsalt, password), 512));
  INSERT INTO table2 VALUES (NEW.idn, NEW.username, NEW.patient_id);
END$$    

Notas sobre el gatillo
Nunca debe almacenar contraseñas sin cifrar en una base de datos.
Almacenelas siempre como un hash salado utilizando la función de hash más segura (actualmente SHA2 con una longitud de clave de 512) , como se muestra en el activador.
Puede probar si alguien tiene la contraseña correcta haciendo lo siguiente:

SELECT * FROM user 
WHERE username = '$username' AND passhash = SHA2(CONCAT(salt,'$password'),512)

Enlaces
http://dev.mysql .com/doc/refman/5.0/en/blackhole-storage-engine.html
http://dev.mysql.com /doc/refman/5.0/en/create-trigger.html
Almacenamiento de contraseñas hash en MySQL
¿Cómo funciona la inyección SQL de las "Bobby Tables"? ¿Trabajo cómico de XKCD?