Which is the best and safest method to program RFQs?

4

Well, folks, I'm now switching to PDO in php, I wanted your opinion to know if the method I'm programming is safe and if I'm programming PDO in the right way because I saw on the internet several ways to program

Example code of how I am doing

<?php
$result_cat = $conexao->query("SELECT * FROM categorias WHERE menu='home' AND activo=1");
$row_cat = $result_cat->fetch(PDO::FETCH_OBJ);
$result_capa = $conexao->query("SELECT * FROM categorias_anexos WHERE id_mae='".$row_cat->id."' AND seccao='capa'");
$row_capa = $result_capa->fetch(PDO::FETCH_OBJ);
?>

Connection to the bank

$host   =   "localhost";
$bd     =   "sabeonde_sabeonde";
$user   =   "[USUARIO]";
$pass   =   "[SENHA]";

try {
$conexao = new PDO('mysql:host='.$host.';dbname='.$bd.';charset=utf8', ''.$user.'', ''.$pass.'');
$conexao->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (PDOException $e) {
       echo 'Error : <br>' . $e->getMessage();
}

Test

$result_capa = $conexao->prepare("SELECT * FROM categorias_anexos WHERE id_mae = :row_cat      AND seccao='capa'");
$result_capa = bindParam(":row_cat", $row_cat->id, PDO::PARAM_INT);
$result_capa->execute();
$row_capa = $result_capa->fetch(PDO::FETCH_OBJ); 
    
asked by anonymous 06.03.2015 / 20:53

2 answers

2
Best practice using Prepared Statements:
$id = 5;
try {
    $conn = new PDO('mysql:host=localhost;dbname=meuBancoDeDados', $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);   

    $stmt = $conn->prepare('SELECT * FROM minhaTabela WHERE id = :id');
    $stmt->execute(array('id' => $id));

    while($row = $stmt->fetch()) {
        print_r($row);
    }
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

 ?>

In this example, we are using the staging method to literally prepare the query before the user data is appended. With this technique, SQL Injection is virtually impossible, because the data is never entered into the SQL query itself. Note that, instead, we use named parameters (: id) to specify placeholders.

The query was executed by passing an array containing the data that should be bound to these placeholders.

$stmt->execute(array('id' => $id));

An alternate but perfectly acceptable approach would be to use the bindParam method, like this: An alternative form that is perfectly acceptable and can be used without fear by anyone who wants to use it, is to use the bindParam method, thus:

$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();

After calling the execute method, there are different ways of receiving the data: an array (the default), an object, and so on. In the above example, the default response is: PDO :: FETCH_ASSOC, which can be easily overridden if needed.

while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
    print_r($row);
}

In the code above, we specify that we want to interact with the result set in the best object-oriented way. Below I'll list some of the options available for this interaction.

  
  • PDO :: FETCH_ASSOC: Returns an array.
  •   
  • PDO :: FETCH_BOTH: Returns an array, indexed by column name and 0-indexed.
  •   
  • PDO :: FETCH_BOUND: Returns TRUE and assigns the values of the columns in your result set to the PHP variables that were tied.
  •   
  • PDO :: FETCH_CLASS: Returns a new instance of the specified class.
  •   
  • PDO :: FETCH_OBJ: Returns an anonymous object, with property names that match the columns.
  •   
    
07.03.2015 / 13:38
1
What you should immediately start to be worry about and if possible change in your designs are two things:

1) do not use mysql_ * since they have been discontinued;

2) NEVER use concatenation of strings in your commands as you mentioned in the example:

SELECT * FROM categorias_anexos WHERE id_mae='".$row_cat->id."' AND seccao='capa'

This is the key point for a SQL injection attack since the attacker can by requests inject commands directly into your query, here's an example:

Let's say I have a query like this:

SELECT * FROM usuario WHERE login = '".$login."' AND password = '".$passwd.'"

In this way it is enough for the "attacker" to send to the variable referring to the following value:

1' OR '1' = '1

In other words, my original command will become:

SELECT * FROM usuario WHERE login = '' AND password = '1' OR '1' = '1'

So this query will be valid and will return something of it since clause 1 = 1 is always valid, ie, the security breach is done.

The answer to the question as mentioned is the use of PreparedStatements .

On your usage example, it is not clear to me what your $conexao->prepare function returns, but if it returns a statement the following usage will be wrong and should be:

$result_capa->bindParam(":row_cat", $row_cat->id, PDO::PARAM_INT);
    
07.03.2015 / 10:34