La seguridad y funcionamiento sin duda uno de los temas más importantes al desarrollar un portal web. La validación de datos, es por tanto fundamental.

El no cuidarnos de esto, puede traernos problemas de inyección SQL, CrossScripting, Cookie Poisoning, amenazas de seguridad en la nube (Cloud Computing) y un largo etc, etc, que compromete la estabilidad del sitio y el recurso más valioso de nuestro sitio "la información".

El filtrado de datos es una de las piedras angulares en cualquier aplicación en el tema de seguridad, independientemente del lenguaje con el cual se desarrolle.

Filtrado de datos

Una de las mayores fortalezas de PHP es su facilidad de uso. Lamentablemente, este mismo beneficio se usa en contra de PHP, programadores con poca experiencia olvidan usar medidas de seguridad o carecen de los conocimientos para generar una clase que valide los datos introducidos por los usuarios finales.

Se han desarrollado diversas clases de validación, algunas mejores que otros, con igual o mayor número de métodos para hacer la misma tarea estas no estan estandarizadas. PHP versión 5 proporciona la extensión Filter cuyo objetivo es realizar esta tarea en forma sencilla, robusta y la estandarización de la entrada de datos del usuario. Las funciones base se presentan a continuación.

Función Descripción
filter_has_var Verifica si la variable del tipo especificado existe
filter_list Devuelve una lista de todos los filtros soportados
filter_var Filtra una variable con un filtro específico. Devuelve los datos filtrados, o FALSE si el filtro falla.
filter_input Obtiene una variable desde afuera de PHP y opcionalmente la filtra

Ejemplo de filter_has_var

La sintaxis es:

filter_has_var(tipo, variable)

Parámetro Descripción
tipo Requerido. específica el tipo que deseamos checar. Los posibles tipos son:
  • INPUT_GET
  • INPUT_POST
  • INPUT_COOKIE
  • INPUT_SERVER
  • INPUT_ENV
variable Requerida. Específica la variable que deseamos checar

El objetivo del ejemplo es tratar de frenar invasiones a la seguridad asegurandonos que no introduzcan datos mediante la URL. Este método no es infalible contra la inyección de código SQL, pero es una aproximación.

<?php
  if (!filter_has_var(INPUT_POST, 'login') or !filter_has_var(INPUT_POST, 'key')) {
    echo('Sin Peligro');
  } else die('Por aquí no entras');
?>

Mediante la función filter_list es posible recuperar la lista de filtros soportados por nuestro servidor y con filter_id recuperados el indentificador del filtro.

Ejemplo del uso de filter_list y filter_id.

<!DOCTYPE html>
<html lang='es'>
<head>
  <meta charset='utf-8' />
  <title>Lista de filtros</title>
  <link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css' rel='stylesheet'>
</head>
<body>
<div class='container'>
  <table class='table table-bordered table-condensed table-hover'>
    <thead>
      <tr>
        <td class="text-center">ID</td>
        <td class="text-center">Nombre del Filtro</td>
      </tr>
    </thead>
    <tbody>
<?php 
  $html = '';
  foreach( filter_list() as $id =>$filter) {
    $html.= '<tr>';
    $html.= '<td class="text-right">'.filter_id($filter).'</td>';
    $html.= '<td><code>'.$filter.'</code></td>';
    $html.= '</tr>';
  }
  $html.= '</tbody></table>';
  echo $html;
?>
</div>
</body>
</html>

Ejemplo de filter_var y filter_input

La validación de datos es una parte integral del trabajo con formularios. Datos válidos los datos presentados pueden dar lugar a problemas de seguridad

A partir del formulario

<!DOCTYPE html>
<html lang='es'>
<head>
  <meta charset='utf-8' />
  <title>Validación de formularios</title>
  <link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css' rel='stylesheet'>
  <link href='dist/css/formValidation.min.css' rel='stylesheet'>  
</head>
<body>
  <div class='container'>
    <form class='form-horizontal' id="forma" name="forma" method="post">
    <fieldset> 
      <legend class="text-center">Validación de formularios</legend>
      <br>
      <div class='form-group'>
        <label class='control-label col-sm-2' for='colega'>Futuro colega</label>
        <div class='col-sm-5'>
          <input id='colega' class='form-control' name='colega' placeholder="Nombre completo">
        </div>
      </div>

      <div class='form-group'>
        <label class='control-label col-sm-2' for='estatura'>Estatura</label>
        <div class='col-sm-2'>
          <input id='estatura' class='form-control' name='estatura' placeholder="mts">
        </div>

        <label class='control-label col-sm-2' for='peso'>Peso</label>
        <div class='col-sm-2'>
          <input id='peso' class='form-control' name='peso' placeholder="Kg">
        </div>
      </div>

      <div class='form-group'>
        <label class='control-label col-sm-2' for='url'>url</label>
        <div class='col-sm-5'>
          <input id='url' class='form-control' name='url' placeholder='p.ejem http://www.prograweb.com.mx'>
        </div>
      </div>

      <div class='form-group'>
        <label class='control-label col-sm-2' for='email'>email</label>
        <div class='col-sm-5'>
          <input id='email' class='form-control' name='email' placeholder='correo electrónico'>
        </div>
      </div>

      <div class='form-group'>
        <label class='control-label col-sm-2' for='ip'>ip</label>
        <div class='col-sm-3'>
          >input id='ip' class='form-control' name='ip' placeholder='192.168.0.54'>
        </div>
      </div>

      <div class="form-group"> 
        <div class="col-sm-offset-2 col-sm-1">
          <button type="submit" class="btn btn-primary">Validar>/button>
        </div>  
      </div>

    </fieldset>
    </form>
    
  <div class='row'>     
     <div class="col-sm-offset-2 col-sm-6" id="message"></div>
  </div>
    
  </div>
<!-- Script jQuery -->
</body>
</html>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js'></script>
<script src='../formValidation/js/formValidation.js'></script>
<script src='../formValidation/js/framework/bootstrap.min.js'></script>
<script>
$(document).ready(function() {
  $('#forma') .formValidation({
    err: {
      container: 'tooltip'
    },
	icon: {
      valid: 'glyphicon glyphicon-ok',
      invalid: 'glyphicon glyphicon-remove',
      validating: 'glyphicon glyphicon-refresh'
    },
    fields: {
      colega: {
        validators: { notEmpty: { message: 'El nommbre no puede ser nulo'} }
      },
	  peso: {
        validators: { between: { min: 40, max: 150, message: 'El peso debe estar entre 40 y 90'} }
	  },
      estatura: {
        validators: {
          numeric: {
            message: 'El valor no es número',
            // The default separators
            thousandsSeparator: '',
            decimalSeparator: '.'
          }
        }
      },
      url: {
        validators: { uri: { message: 'La dirección web es no valida'}}
      },
	  email: {
        validators: { emailAddress: { message: 'Esto no es una dirección de correo valida'} }
      },
      ip: {
        validators: { ip: { message: 'Proporcione una dirección IP valida'} }
      }
    }
  })
  .on('err.field.fv', function(e, data) {
    // Get the tooltip
    var $icon = data.element.data('fv.icon'), title = $icon.data('bs.tooltip').getTitle();
   
    // Destroy the old tooltip and crete a new one positioned to the right
    $icon.tooltip('destroy').tooltip({
      html: true,
      placement: 'right',
      title: title,
      container: 'body'
    });
  })
  
  .on('success.form.fv', function(e) {
      // Prevent form submission
      e.preventDefault();

      // Get the form instance
      var $form = $(e.target);
        
      $.post('0430filter_var_input.php', $('#forma').serializeArray(),
	          function(data) { $('#message').html(data); }
      );
    });
	
    // Reset the Tooltip container form
    $('#resetButton').on('click', function(e) {
        var fields = $('#tooltipContainerForm').data('formValidation').getOptions().fields,
            $parent, $icon;

        for (var field in fields) {
            $parent = $('[name="' + field + '"]').parents('.form-group');
            $icon   = $parent.find('.form-control-feedback[data-fv-icon-for="' + field + '"]');
            $icon.tooltip('destroy');
        }

        // Then reset the form
        $('#tooltipContainerForm').data('formValidation').resetForm(true);
    });
	
  });
  </script>
<?php
  // Permite manejar acentos 
  header('Content-Type: text/html; charset=iso-8859-1');
  if($_SERVER['REQUEST_METHOD'] == 'POST') {
    $colega = filter_input(INPUT_POST, 'colega', FILTER_SANITIZE_STRING);
    if ($colega === false or empty($colega) or trim($colega) == '' )  {
        echo 'El nombre es un campo requerido! <br>';
    } else echo "Hola $colega <br>"; 

    $options = array('options'=> array('min_range'=>40, 'max_range'=>150));
    $peso = filter_input(INPUT_POST, 'peso', FILTER_VALIDATE_INT, $options);
    if ($peso === false) {
         echo "Escriba un peso válido entre 40 y 150 kg.<br>";
    } else { echo "$peso kg es un peso válido.<br>";}
	$estatura = $_POST['estatura'];
    if (!filter_var($estatura, FILTER_VALIDATE_FLOAT)) {
       echo "$estatura  no es una variable flotante <br>";
    } else echo "$estatura  es una dato flotante válido<br>";
    $url = $_POST['url'];
    if (filter_var($url, FILTER_VALIDATE_URL)) {
      echo "La url $url es válida <br>";
    } else echo "La url $url no es válida! <br>"; 
    $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
    if ($email === false) {
        echo 'El email es un campo requerido! <br>';
    } else echo "$email es una dirección de correo válida<br>";
	$ip = filter_input(INPUT_POST, 'ip', FILTER_VALIDATE_IP);
    if($ip === false) {
        echo 'No es una IP válida <br>';
    } else echo "$ip es una IP válida <br>"; 
  } else echo "Por aqui no puedes entrar <br>";	 
?>

Para saber más consulte aquí