1

I am designing a simple form that will be used only be me on a password protected web page. However, I have been told I should still design my form to prevent SQL injection attacks. Since I knew nothing about PHP until only a few days ago, I feel less than confident I've followed the tutorials correctly. Is the following code still vulnerable?

<html>
<body>
<form action="gobacktopage.com">
    <input type="submit" value="Add Another" />
</form>
</body>
</html>


<?php
$servername = "myserver.amazonaws.com";
$username = "myusername";
$password = "mypassword";
$dbname = "desireddatabase";

$verse= $_POST['verse'];
$book= $_POST['book'];
$reference = $_POST['reference'];
$cleanverse = addslashes($verse);


// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

if ($stmt = $conn->prepare("INSERT INTO myverses (versetext, book, reference) VALUES (?, ?, ?)")) {

    // Bind the variables to the parameter as strings. 
    $stmt->bind_param("sss", $cleanverse, $book, $reference);

    // Execute the statement.
    $stmt->execute();

    // Close the prepared statement.
    $stmt->close();

}


$conn->close();
?>
Dakota Lynch
  • 169
  • 2
  • 11

1 Answers1

0

Yes, since you are using the prepared statement you are safe from sql injection.

This part of the code protects you.

// Bind the variables to the parameter as strings. 
$stmt->bind_param("sss", $cleanverse, $book, $reference);

The other best practices you might incorporate in your code might be:

  1. To check the maximum string length that you are expecting from the user and to truncate it, if they exceed that.
  2. To disallow any html input, if you are not expecting them by using something like strip_tags or html purifier libraries.
  3. You can also look into how to implement CSRF.
Kamal Soni
  • 1,522
  • 13
  • 15
  • @aendeerei yes you are right in this context, but I still think the important bit is still bind_param. Since you can do something like this in prepare `$stmt = $conn->prepare("SELECT * FROM ADMIN WHERE USER='ADMIN'")` and it would still work. – Kamal Soni Feb 27 '18 at 02:19
  • Right indeed. Then you can do only this: `$result = $mysqli->query("SELECT * FROM ADMIN WHERE USER='ADMIN'")` and you are still on the 100% safe side. I mean, when we talk about security, we talk about user input (in this matter). Then both preparing and binding count. –  Feb 27 '18 at 02:25
  • @aendeerei You can correct me if I am wrong, but what I saying is that prepare statements don't escape anything. If you only use prepare statement than your code would look like `SELECT * FROM ADMIN WHERE USER='.$_POST['admin']`. Do you think this would stop sql injection? – Kamal Soni Feb 27 '18 at 02:36
  • No, it wouldn't. But, since user input is involved, this would be a wrong use of _prepare_ I would say. The correct case is only the one formed from both operations, correctly applied. –  Feb 27 '18 at 02:44