Skip to main content
PHP

Trucos para el filtrado de datos SQL

Por 6 diciembre, 2020Sin comentarios
Filtrado contra la inyección SQL

Hace un tiempo escribí un post sobre la prevención de inyección SQL con mysqli_escape_real_string(). Si quieres saber más sobre la inyección SQL te dejo el enlace:

Como evitar hackeos de inyección SQL

Esta vez te dejaré algunos trucos para hacer un filtrado más completo y personalizado. Por ejemplo, tenemos diferentes funciones nativas de PHP o mysql para filtrar los datos antes de guardarlos:

Al principio hemos hablado de mysqli_real_string(). Esta función escapa caracteres especiales de una cadena como las comillas. De esta manera, anulas el intento de hackeo mediante instrucciones SQL disfrazadas en los datos de entrada.

Otra función nativa de PHP es filter_var(). Esta función acepta un segundo valor para indicarle el tipo de filtro que queremos hacerle a la variable. Hay filtros de validación y saneamiento. Esta función viene bien si sabemos el tipo de dato que vamos a recoger como un email, un teléfono, un número entero, booleano, etc… Cuando saneamos la variable, elimina cualquier carácter especial que no corresponda con el tipo de dato. Por ejemplo, si sabemos que vamos a recoger un string que es un email podríamos utilizar el filtro de validación y saneamiento:

if( filter_var( $var, FILTER_VALIDATION_EMAIL ) ) {
     $var = filter_var( $var, FILTER_SANITAZE_EMAIL ); 
}

En los siguientes enlaces puedes encontrar todos los filtros de validación y saneamiento existentes.

Aparte de las funciones nativas de PHP, podemos crear funciones personalizadas que nos permite hacer un saneamiento completo de los datos y así nuestra aplicación o web sera mucho más segura. Por ejemplo, si en vez de escapar los caracteres especiales, queremos detectar si un string contiene sentencias SQL, podemos usar la siguiente función:

function _detect_sql_injection( $string ) {
	$sql_injection = false;
	$forbidden = array(
	    'select * ',
	    'select ',
	    'union all ',
	    'union ',
	    'insert',
	    'where'
	);

	$string = urldecode( strtolower( $string ) );

	foreach( $forbidden as $operator ) {
		if( strpos( $string, $operator ) !== false || preg_match( "/".$operator."/i", $string ) ) {
			$sql_injection = true;
			break;
		}
	}

	return $sql_injection;
}

Si tenemos entradas de datos que contienen HTML, pero no queremos que un ciber-delincuente lo aproveche para meter código malicioso como scripts, iframes, etc… Podemos usar esta otra función:

function _detect_bad_html( $html ) {
	$bad_html  = false;
	$forbidden = array( 'script', 'iframe ', 'embed', 'noscript' );

	foreach( $forbidden as $element ) {
		if( strpos( $html, "<$element" ) !== false || strpos( $html, "</$element>" ) !== false ) {
			$bad_html = true;
			break;
		}
	}

	return $bad_html;
}

Si lo que queremos es limpiar todas las etiquetas html, scripts y styles de una cadena, podemos usar la siguiente función:

function cleanHTMLinput( $input ) {
  $search = array(
    '@<script [^>]*?>.*?@si',
    '@<[/!]*?[^<>]*?>@si',
    '@<style [^>]*?>.*?</style>@siU',
    '@<![sS]*?--[ tnr]*>@'
  );
  
    $output = preg_replace( $search, '', $input );
    return $output;
}

Si no queremos complicarnos en exceso y solo queremos sanear los datos para evitar la inyección SQL de forma efectiva, entonces la mejor opción sigue siendo mysqli_real_escape_string(). Os dejo otra función simple, pero que permite sanear cadenas o arrays. Ademas, es compatible con servidores que tengan activo las magic_quotes, que escapan las comillas de forma automática.

function sanitize_vars( $input ) {
    if( is_array( $input ) ) {
        foreach( $input as $key => $val ) {
            $output[$key] = sanitize( $val );
        }
    }
    else {
        if( get_magic_quotes_gpc() ) {
            $input = stripslashes( $input );
        }
        $output = mysqli_real_escape_string( $input );
    }
    return $output;
}
Jairo Calero

Desarrollador web frontend y backend, especialista en webs app desarrolladas en PHP y Javascript. Experto en HTML, CSS3, PHP y Javascript con frameworks y librerías como jQuery, Angular y Bootstrap. Gestor de herramientas SEO como Google Analytics, Search Console, SEMrush o Hotjar. Email marketing y Big data.

Deja tu respuesta