Al unir tablas, uso modelos SQL de Zend Framework. Como ejemplo, modifiqué mi código real, pero creo que obtendrá el punto:
$this->getSelect()->join(
array('sections' => $sectionsTableName),
'main_table.banner_id = pages.banner_id',
array()
)
->where("sections.section= '$section' OR sections.section = '0' OR (sections.section = '6' AND ? LIKE main_table.url)",$url)
->group('main_table.banner_id');
La página se carga con ajax y el parámetro $ section se envía como parámetro GET ( www.example.com/controllerName/index/display/3?paremeter1=example§ion=www.example2.com
).
Ahora aquí está el problema si alguien realiza algo como esto:
www.example.com/controllerName/index/display/3?paremeter1=example&url=(SELECT 3630 FROM(SELECT COUNT(*),CONCAT(0x7170786a71,(SELECT (ELT(3630=3630,1))),0x717a716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)
De esta manera, el usuario puede volcar toda la base de datos. Los datos no se mostrarán, pero aún así SQL realizará un volcado que puede causar una sobrecarga de sql.
Preguntas:
- ¿Cuál es la mejor manera de prevenir tal escenario?
- Ahora estoy preocupado por los clientes anteriores. ¿Es posible con este código realizar aún más acciones de riesgo, como eliminar o alterar la tabla? Supongo que no porque no pueda poner ninguna otra declaración que SELECT dentro de subselect para que DELETE produzca un error de sintaxis sql. Estoy en lo cierto?
ACTUALIZACIÓN: Mi ejemplo no es una ilustración adecuada de la inyección SQL porque hay 'signos alrededor de $ secciones y, por lo tanto, no será posible realizar la inyección. De todos modos, esto sería posible cuando se espera un valor entero y cuando no se filtra la entrada entera. Mira mi comentario a continuación.
fuente
$db = Mage::getSingleton('core/resource')->getConnection('core_read');
e$db->quote()
incluso en tu caso mira$db->quoteInto
. Si$this
es un recurso, que podría hacer:$this->getConnection('core_read')->quoteInto()
si se trata de una colección que podría hacer:$this->getResource()->getConnection('core_read')->quoteInto()
. Entre esas líneas. Si eso ayuda a guiarte hacia tu objetivo.'
signo antes del(
signo y, por lo tanto,(SELECT
o cualquier otra cosa será igual que una cadena y no funcionará. Cuando el campo es entero,'
no es necesario y hace posible tal escenario. Pero el entero siempre debe filtrarse, porintval()
lo que tampoco es un problema.'
? Entonces' AND (SELECT ...) '
? Por cierto, no creo que Zend no esté citando esto ... Y si usa enlaces, PDO se encargará de esto. Simplemente nunca use concatenaciones de picadura como esta:"sections.section= '$section'"
Respuestas:
Validar su entrada!
Tan bueno y tanto como puedas.
Algunas sugerencias para su validación:
Verifique la longitud de la variable que obtiene a través del parámetro GET. No hay necesidad de aceptar una cadena larga interminable.
Validar para un nombre de dominio. ¿Qué tipo de formato tienen sus nombres de dominio esperados? ¿Es siempre www.midominio.tld? Cree una expresión regular que verifique si hay una coincidencia o (mejor) uso
Zend_Validate_Hostname
:Lista blanca: ¿Sabe qué nombres de dominio esperar? Puede crear una lista de dominios permitidos y verificarlos. Deja el resto.
Lista negra de nombres de dominio y / o caracteres: si espera un nombre de dominio, no es necesario aceptar ningún otro carácter que no sea az y 0-9 y "." (a menos que esté trabajando con nombres de dominio especiales).
fuente