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.
'
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, por intval()
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'"
$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.