quinta-feira, 26 de outubro de 2017

Publicado quinta-feira, outubro 26, 2017 por com 0 comentário

Bloqueando Injeção de código XSS

Para complementar o post Prevenção do SQL Injection hoje vou trazer um outro método de tratar a injeção SQL, e também já evitar o ataque XSS.



Segundo a definição mais espalhada na internet, o XSS é uma vulnerabilidade que permite ao atacante inserir códigos maliciosos nessas páginas, para que sejam executados no momento em que tais páginas forem acessadas. Geralmente esses códigos são em JavaScript, e muitas vezes usados para sequestro de sessão (Session Hijacking), incluir uma rotina JavaScript, PHP ou uma query SQL. Um tópico que vamos abordar em outro post.

Como se proteger?

Para se proteger é necessário você verificar e filtrar todas as entradas via $_GET e $_POST, a fim de eliminar qualquer injeção HTML, PHP ou SQL. Um meio para bloquear a injeção de códigos é através da função htmlspecialchars. Exemplo:

 <?php $pesquisa = htmlspecialchars($_GET['pesquisa']); ?>  

Além disso, para evitar invasões no banco de dados, recomendo realizar as consultas SQL com parâmetros filtrados:
$con  = new mysqli("localhost", "user", "pass", "test");
if (mysqli_connect_errno()) die(mysqli_connect_error());

$sql  = "INSERT INTO artigos (titulo, corpo, date) VALUES (?, ?, now())";
$stmt = $con->prepare($sql);
$ok   = $stmt->bind_param("ss", $_POST[title], $_POST[body]);

if ($ok && $stmt->execute())
  header('Location: index.php');
else
  die('Error: '.$con->error);
O erro mais comum na programação é passar os parâmetros diretamente na consulta, resultando em vulnerabilidades em todo o site:
$id  = $_GET['id'];
$sql = "SELECT * FROM TABELA WHERE ID=".$id; //ID ou uma consulta maliciosa

Com as consultas passando por parâmetros, além de eliminar invasões por Injection SQL, também evita XSS. Contudo, apenas a função htmlspecialchars não vai eliminar os ataques de XSS avançado. Para isso, é necessário usar uma classe Anti-XSS:


 <?php  
 class AntiXSS {  
   public static $err = "XSS Detected!";  
   /*  
    * @function  : setEncoding  
    * @return   : String  
    * @parameters : str: Content you want to change the character encoding  
    *        newEncoding: Character encoding you want set  
    * @description: Convert the character encoding of the string  
    *        to newEncoding from currentEncoding. currentEncoding  
    *        detecting by function so you only need give str and  
    *        newEncoding to the setEncoding function.  
    */  
   public static function setEncoding($str, $newEncoding) {  
     $encodingList = mb_list_encodings();  
     $currentEncoding = mb_detect_encoding($str, $encodingList);  
     $changeEncoding = mb_convert_encoding($str, $newEncoding, $currentEncoding);  
     return $changeEncoding;  
   }  
   /*  
    * @function  : blacklistFilter  
    * @return   : String  
    * @parameters : str: Content you want to filter with blacklist  
    * @description: Filter the content by blacklist method. Library use  
    *        RSnake's XSS attack vectors. To add new attack vectors  
    *        I'm continue to research.  
    */  
   public static function blacklistFilter($str) {  
     if (preg_match("/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t(.*)>(.*)/i", $str) > 0) {  
       return $str;  
     } else {  
       return self::$err;  
     }  
   }  
   /*  
    * @function  : whitelistFilter  
    * @return   : String  
    * @parameters : str: Content you want to filter with blacklist  
    *        whiteFilterPattern: Some patterns for filter the  
    *        data types.  
    * @description: Filter the content by whitelist method. To add  
    *        new data types, I'm continue to research.  
    */  
   public static function whitelistFilter($str, $whiteFilterPattern) {  
     switch ($whiteFilterPattern) {  
       case "string":  
         $pattern = "([a-zA-Z]+)";  
       break;  
       case "number":  
         $pattern = "([0-9]+)";  
       break;  
       case "everything":  
         $pattern = "(.*)";  
       break;  
       default:  
         $pattern = "([0-9a-zA-Z]+)";  
       break;  
     }  
     if(preg_match("/^$pattern $/i", $str) > 0) {  
       return $str;  
     } else {  
       return self::$err;  
     }  
   }  
   /*  
    * @function  : setFilter  
    * @return   : String  
    * @parameters : str: Content you want to filter with blacklist  
    *        filterMethod: Library have 3 method.  
    *         -Black Method  
    *         -White Method  
    *         -Gray Method  
    *        filterPattern: Some patterns for filter the  
    *        data types. (You can only use with whitelist filter)  
    *        noHTMLTag: Use PHP's strip_tags function to  
    *        remove HTML tags from content.  
    * @description: Filter the content by method.  
    */  
   public static function setFilter($str, $filterMethod, $filterPattern = NULL, $noHTMLTag = NULL) {  
     if (urldecode($str) > 0) {  
       $str = urldecode($str);  
     }  
     if ($noHTMLTag == 1) {  
       $str = strip_tags($str);  
     }  
     $str = strtolower($str);  
     $str = addslashes($str);  
   $str = htmlspecialchars(trim($str));  
     switch($filterMethod) {  
       case "black":  
         $str = self::blacklistFilter($str);  
       break;  
       case "white":  
         $str = self::whitelistFilter($str, $filterPattern);  
       break;  
       default:  
       break;  
     }  
     return $str;  
   }  
 }  
 ?>  

Fonte: Stackoverflow, Github
      edit

0 comentários:

Postar um comentário