2009-10-13 20 views
5

Históricamente, siempre he utilizado¿Están las consultas preparadas por PHP MySQLi con los parámetros enlazados seguros?

mysql_real_escape_string() 

para todas las entradas derivadas de los usuarios que acaba de tocar la base de datos.

Ahora que me he convertido completamente a MySQLi y estoy usando consultas preparadas con parámetros enlazados, ¿he eliminado efectivamente la posibilidad de ataques de inyección SQL?

Estoy en lo correcto al decir que ya no necesito

mysql_real_escape_string()? 

Este es mi entendimiento y la base de un proyecto mío: http://sourceforge.net/projects/mysqldoneright/files/Base/MysqlDoneRight-0.23.tar.gz/download

Esto no es algo que quiero conseguir equivocado, aunque como ahora que lo he lanzado, podría afectar a otros también.

Toda la entrada proporcionada por el usuario ahora terminará en bind_parms.
Las consultas proporcionadas en la fase de preparación son estáticas.

Respuesta

6

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.

+0

Sí. ¿Notó que no podía hacer la ORDEN POR? poco con los parámetros. Buena respuesta. –

+0

¿Recibí un voto negativo? Downvoter, debe describir por qué cree que esta respuesta no es satisfactoria. Quizás puedo mejorarlo. –

13

Sí. El uso de la consulta preparada escapará a los parámetros.

+0

Corto, dulce y preciso. – ceejayoz

+0

Gracias. Solo quería asegurarme de no perderme algo obvio. Tiendo a hacer eso. –

1

Cuando vincula parámetros a una instrucción preparada, escapa de los datos automáticamente, por lo que no debe escapar antes de enviarla. El doble escape suele ser algo malo. Por lo menos, produce resultados desagradables con más caracteres escapados más adelante.

Cuestiones relacionadas