How to filter the input of a form to the Database?

Asked

Viewed 55 times

2

I have a function to filter input data to send to the database, I’ve been looking a little while and I thought that still has to improve, the default that I use is UTF_8, the data comes from forms and are processed to be written to mysql.

<?php
if( !function_exists('filtra_var') ){
    function filtra_var($var) {
        $var = trim($var);
        $var = strip_tags($var);
        $var = addslashes($var);
        $var = htmlspecialchars($var, ENT_QUOTES, 'UTF-8');
        $var = fgetss($var);
        return $var;
    }
}
?>

In SQL I also use

mysqli_real_escape_string($conn,$var);

Any recommendation on how to improve protection against Injection/malicious?

1 answer

2


In PHP there are already native functions that work best to filter data entries.

The functions filter_* allow a series of validations and sanitizers where it is possible to do virtually everything.

Follow the list of possible filters:

http://php.net/manual/en/filter.filters.php

It is possible to import directly from the variables of $_POST and $_GET from the filter_input() or even import and clear the entire form with filter_input_array. In the PHP documentation we have the following example:

<?php

/* dados no post:
$_POST = array(
    'product_id'    => 'libgd<script>',
    'component'     => '10',
    'versions'      => '2.0.33',
    'testscalar'    => array('2', '23', '10', '12'),
    'testarray'     => '2',
);
*/

$args = array(
    'product_id'   => FILTER_SANITIZE_ENCODED,
    'component'    => array('filter'    => FILTER_VALIDATE_INT,
                            'flags'     => FILTER_REQUIRE_ARRAY,
                            'options'   => array('min_range' => 1, 'max_range' => 10)
                           ),
    'versions'     => FILTER_SANITIZE_ENCODED,
    'doesnotexist' => FILTER_VALIDATE_INT,
    'testscalar'   => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_REQUIRE_SCALAR,
                           ),
    'testarray'    => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_REQUIRE_ARRAY,
                           )

);

$myinputs = filter_input_array(INPUT_POST, $args);

var_dump($myinputs);
?>

The above example will print:

array(6) {
  ["product_id"]=>
  array(1) {
    [0]=>
    string(17) "libgd%3Cscript%3E"
  }
  ["component"]=>
  array(1) {
    [0]=>
    int(10)
  }
  ["versions"]=>
  array(1) {
    [0]=>
    string(6) "2.0.33"
  }
  ["doesnotexist"]=>
  NULL
  ["testscalar"]=>
  bool(false)
  ["testarray"]=>
  array(1) {
    [0]=>
    int(2)
  }
}

After the clean input, a next layer as you commented is the insertion into the bank. The most optimized way to work with this is with Prepared Statements. They already apply string escape making your code simpler. Your code would come out of this:

$titulo = mysql_real_escape_string($titulo);
$autor_livro = mysql_real_escape_string($autor_livro);
$result = mysql_query("INSERT INTO tbl_livro VALUES (NULL, '$titulo', '$autor_livro')");

For that reason:

$stmt = $pdo->prepare("INSERT INTO tbl_livro VALUES (NULL, :titulo, :autor_livro)");
$stmt->bindParam(':titulo', $titulo);
$stmt->bindParam(':autor_livro', $autor_livro);

$stmt->execute();

This is a very quick introduction on these subjects, but it is a reference to know how to do and how it happens under the table. All this and some other things are abstracted by frameworks like Laravel, Symfony, so you don’t have to worry about implementing all this.

  • Thanks gmsantos, I will practice even more with all the tips.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.