No es tan simple. Puede utilizar parámetros vinculados en lugar de la interpolación de variables de aplicación en expresiones SQL en lugar de valores literales única:
$sql = "SELECT * FROM MyTable WHERE id = ".$_GET["id"]; // not safe
$sql = "SELECT * FROM MyTable WHERE id = ?"; // safe
Pero lo que si usted necesita para hacer parte de la consulta dinámica, además de un valor literal?
$sql = "SELECT * FROM MyTable ORDER BY ".$_GET["sortcolumn"]; // not safe
$sql = "SELECT * FROM MyTable ORDER BY ?"; // doesn't work!
El parámetro siempre se interpretará como un valor, no como un identificador de columna. Puede ejecutar una consulta con ORDER BY 'score'
, que es diferente de ORDER BY score
, y usar un parámetro se interpretará como el anterior - una cadena constante 'score'
, no el valor en la columna denominada score
.
De modo que hay muchos casos en los que debe utilizar SQL dinámico e interpolar variables de aplicación en la consulta para obtener los resultados que desea. En esos casos, los parámetros de consulta no pueden ayudarte. Todavía debe estar atento y codificar a la defensiva para evitar fallas en la inyección de SQL.
Ninguna biblioteca de marcos o de acceso a datos puede hacer este trabajo por usted. Siempre puede construir una cadena de consulta SQL que contenga un error de inyección de SQL, y lo hace antes de que la biblioteca de acceso a datos vea la consulta SQL. Entonces, ¿cómo se supone que debe saber qué es intencional y qué es un defecto?
Éstos son los métodos para lograr consultas SQL seguras: entrada
filtro. Rastrea cualquier dato variable que se inserte en tus consultas SQL. Use la entrada filters para eliminar los caracteres ilegales.Por ejemplo, si espera un número entero, asegúrese de que la entrada esté restringida para ser un número entero.
Salida de escape. La salida en este contexto puede ser la consulta SQL que envía al servidor de la base de datos. Sabe que puede usar parámetros de consulta SQL para valores, pero ¿qué pasa con el nombre de una columna? Necesita una función de escape/cita para identificadores, al igual que el antiguo mysql_real_escape_string()
es para valores de cadena.
Revisiones de código. Haz que alguien sea un segundo par de ojos y revisa tu código SQL, para ayudarte a detectar los lugares donde no has usado las dos técnicas anteriores.
Sí. ¿Notó que no podía hacer la ORDEN POR? poco con los parámetros. Buena respuesta. –
¿Recibí un voto negativo? Downvoter, debe describir por qué cree que esta respuesta no es satisfactoria. Quizás puedo mejorarlo. –