Why do they say $_GET in PHP is insecure against sql Injection?

Asked

Viewed 368 times

6

Well, my question is simple.

I’ve been hearing a lot of stories lately that $_GET in PHP is insecure against sql Injection.

Could you tell me why?

Thank you.

  • You can leave an open port for an SQL-Injection attack that is nothing more than inserting an SQL code into a URL parameter that will be sent directly to the database

1 answer

16


Is not the $_GET which is unsafe, the problem is how it uses it. The data may come by $_GET, $_POST, $_COOKIE or even a string previously saved to a file and later added to a query execution.

The problem is how to directly pass the values in the query, for example:

SELECT * FROM tabela WHERE nome LIKE '%{$_GET['nome']}%'

In this way it would be possible to do something like http://site/pagina.php?nome=';QUERY and create this:

SELECT * FROM tabela WHERE nome LIKE '';QUERY'

Of course in the above case at most you would get a syntax failure, in general the API does not allow multiple queries, now imagine that the data of a SELECT is based on an id saved in the session and the products that the user can view in a panel are only those with the ID (id_dono) his:

SELECT * FROM produtos WHERE id_produto={$_GET['idproduto']} AND id_dono={$_SESSION['idautenticado']}

But if you type that, access this http://site/pagina.php?idproduto=6 -- and create this:

SELECT * FROM produtos WHERE id_produto=6 -- OR id_dono=5

This way the user ignored everything that comes after -- and you can get private product data from other users in an alleged dashboard where you would control your products.

Another example would be to manipulate any column of a table:

UPDATE dados SET nome='%{$_GET['nome']}%' WHERE id={$_GET['id']}

Suppose we have columns that shouldn’t be changed, but if you do something like http://site/pagina.php?id=1&nome=',outracoluna='xxxxxx you will have control over any column of the table as it will generate something like:

UPDATE dados SET nome='',outracoluna='xxxxxx' WHERE id=1

Read this from how to avoid:

A simple example is to use bindValue or bindParam:

PDO+bindValue:

$db = new PDO('mysql:host=localhost dbname=teste', 'usuario', 'senha');
    
$stmt = $db->prepare('SELECT * FROM tabela WHERE nome LIKE ?');

$stmt->bindValue(1, '%' . $_GET['busca'] . '%'); // passado diretamente

$stmt->execute();

PDO+bindParam:

$stmt = $db->prepare('SELECT * FROM tabela WHERE nome LIKE :consulta');

$stmt->bindParam(':consulta', $nome);

$nome = '%' . $_GET['consulta'] . '%';

Mysqli+bind_param:

mysqli only works with bind_param, that is to say nay there is a bind_value

$db = new mysqli('localhost', 'usuario', 'senha', 'teste');

$stmt = $db->prepare('SELECT * FROM tabela WHERE nome LIKE ?');

if(!$stmt){
    echo 'erro na consulta: '. $db->errno .' - '. $db->error;
} else {
    $stmt->bind_param('s', $nome);

    $nome = '%' . $_GET['consulta'] . '%';

    $stmt->execute();
}

bindValue and bindParam

  • bindParam works with references, ie only variables and constants should be used. If it is a variable the value can be changed later, but before the execute

  • bindValue works with any type of value, constant variable or directly past

Read more on: What is the difference between bindParam and bindValue?

  • Specifically what bindValue does?

  • 1

    @Gonçalo many of these doubts already have answer on the site, anyway I added the answer.

  • 1

    Excellent reply, thank you!

Browser other questions tagged

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