How to prevent SQL-injection when using MySQLi - php

I'm building a simple form and want to secure this against the following SQL-injections:
- blind-injection
- boolean-based
- blind injection
- UNION query-based
- Stacked queries
- error-based injections
I thought that I had it all secured, but when I run SQL-map it still exploits my database.
<?php
$input = $_GET['input'];
if ($input) {
$db = mysqli_connect("localhost", "sec", "dubbelgeheim", "bookshop");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$escaper = real_escape_string($input);
$statement = $db->prepare("SELECT * FROM productcomment WHERE ProductId = ? LIMIT 1");
$statement->bind_param("s", $escaper);
$statement->execute();
$result = $statement->get_result();
$statement->close();
$count = $result->num_rows;
if ($count > 0) {
while ($row = $result->fetch_assoc()) {
echo "Product:" . $row['ProductId'] . "<br>";
echo "Annotation:" . $row['Comment'] . "<br>";
echo "TestOK!<br>";
}
}
else {
echo 'No record!';
}
$result->free();
$db->close();
}
?>
Did I forget something?
Can anyone help?
Thanks in advance!

Your problem is caused by you displaying mysqli_connect_error(). This is OK for testing but should NOT be used in production code. You also don't need $escaper = real_escape_string($input);.
Try this instead
/* check connection */
if (mysqli_connect_errno()) {
file_put_contents('MySQLiErrors.txt',date('[Y-m-d H:i:s]'). mysqli_connect_error()."\r\n", FILE_APPEND);
exit();
}else{
$statement = $db->prepare("SELECT * FROM productcomment WHERE ProductId = ? LIMIT 1");
$statement->bind_param("s", $input);
}

Related

sql prepared statement not showing output

I am new to prepared statements. This function is not showing any output. What could the be problem?
function selectFwhere($id) {
$con = mysqli_connect('localhost','root','','car_rental');
$sql = mysqli_prepare($con,'SELECT * FROM `car_admin` WHERE admin_id = ?') or die("Unable to prepare statement: " . $con->error);
$sql->bind_param('i',$id);
$sql->execute();
$result = $sql->get_result();
while($row = $result->fetch_assoc() ){ echo " ".$row['admin_username']; }
$sql->close();
$con->close();
selectFwhere(1);
}
You need to move the line selectFwhere(1); outside the function body, after the closing }

Could not be able to print Mysqli query result in php

I want to print result of a Mysqli query, But when I try to do as following way, It does not return any values or error. The code does not go through the while loop. What would be the wrong with my code, Please help me!
<?php
$mysqli = new mysqli("localhost", "root", "", "domains");
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
$part = explode(".", $str);
$part1 = $part[0];
$part2 = $part[1];
$sql = "SELECT
DomainCategory.Name
FROM
DomainName_Client,
DomainNameType,
DomainCategory,
OrderDomain_Client
WHERE
DomainName_Client.Name = '$part1'
AND DomainNameType.Name = '$part2'
AND DomainName_Client.TypeID = DomainNameType.ID
AND DomainCategory.ID = DomainName_Client.DomainCategoryID
AND OrderDomain_Client.DomainNameID = DomainName_Client.ID";
$result = $mysqli->query($sql);
if (!$result = $mysqli->query($sql)) {
die('There was an error running the query ' . $mysqli->error . ']');
}
while ($row = $result->fetch_assoc()) {
echo 'Total results: ' . $result->num_rows;
}
?>
First you check the number of results returning in the sql query using the following code and after that you print it using while or for loop.
echo $result->num_rows;

How to check if MySQL results returned empty in PHP?

How to check MySQL results are empty or not. If MySQL query results are empty then else condition should not be executed.
In case MySQL results in data there & in else condition my error my message is there but it is not showing any error message.
I have tried the following code but not showing any alert or echo message on the screen.
<?php
$sql = "select * from hall_search_data_1 where rent BETWEEN '".$_SESSION['amount1']."' AND '".$_SESSION['amount2']."'";
$res = mysql_query($sql);
if (!empty($res)) {
while ($row = mysql_fetch_row($res)) {
// here my data
}
} else {
echo "no results found";
}
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
$conn = new mysqli($servername, $username, $password, $dbname);
$sql = "SELECT id, firstname, lastname FROM MyGuests";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "id: " . $row["id"] . " - Name: " . $row["firstname"] . " " . $row["lastname"] . "<br>";
}
} else {
echo "0 results";
}
$conn->close();
?>
Check number of rows
$result = mysqli_query($conn, $sql);
$rowcount=mysqli_num_rows($result);
if($rowcount > 0){
echo "Number of rows = " . $rowcount;
}
else
{
echo "no record found";
}
You can use mysql_num_rows to get count of number of rows returned from query.
if(mysqli_num_rows($res) > 0)
{
// rest of your stuff
}
else
{
echo "No records found.";
}
Note: mysql is deprecated instead use mysqli or PDO as seen above
Security Tip First of all stop using the mysql_* functions because they are not secure for production and later versions has stopped support for this API. So if accidentally you used those function in production then you can be in trouble.
It is not recommended to use the old mysql extension for new development, as it was deprecated in PHP 5.5.0 and was removed in PHP 7. A detailed feature comparison matrix is provided below. More Read
For your answer you have to only check no of rows is zero or not
Read this Post at php documentation with Example.
mysqli_num_rows
mysql_* API has been removed from PHP long time ago. To access the database you should use PDO. Checking if PDO has returned any results is actually pretty simple. Just fetch the results and if the array is empty then there was nothing returned from MySQL.
$stmt = $pdo->prepare('SELECT * FROM hall_search_data_1 WHERE rent BETWEEN ? AND ?');
$stmt->execute([$_SESSION['amount1'], $_SESSION['amount2']]);
$records = $stmt->fetchAll();
if ($records) {
foreach ($records as $row) {
// your logic
}
} else {
echo 'No records found!';
}
There is also mysqli library and if you are stuck using it you have to do a little more work, but the idea is the same. Fetch all results and if nothing was fetched then it means MySQL returned no rows.
$stmt = $mysqli->prepare('SELECT * FROM hall_search_data_1 WHERE rent BETWEEN ? AND ?');
$stmt->bind_param('ss', $_SESSION['amount1'], $_SESSION['amount2']);
$stmt->execute();
$records = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
if ($records) {
foreach ($records as $row) {
// your logic
}
} else {
echo 'No records found!';
}
You can use mysql_num_rows(); to check your query return rows or not
$sql = "select * from hall_search_data_1 where rent BETWEEN '".$_SESSION['amount1']."' AND '".$_SESSION['amount2']."'";
$res = mysql_query($sql);
$rows=mysql_num_rows($res);
if($rows>0)
{
echo "data return from query";
}else{
echo "data not return";
}
Note:- mysql is deprecated instead use mysqli or PDO

How to separate mysql row values by comma using php?

I have tried the following code to output each student father_contact by firstly merging them and secondly separating each number by comma and could not make it working. Please help me.
$sql = "SELECT Fathers_Contact FROM student WHERE Class ='$class' AND Section='$s' and Year='$y'";
$result = mysql_query($sql);
if (!$result) {
die("Query not working");
}
$mbno_arr = array();
while ($row = mysql_fetch_array($result)) {
$mbno_arr[] = $row[0];
}
$mbno_list = implode(',', $mbno_arr);//expect here is: 9867656543,9867656443,9867654543
if(empty($mbno_list)){
echo "No number is there";
exit;
}
if(empty($msg)){
echo "Message empty!";
exit;
}
Father_contact is ten digit mobile no.
// Escapes special characters in a string for use in an SQL statement
$SQL = sprintf(
"SELECT Fathers_Contact
FROM student
WHERE Class = '%s' AND Section = '%s' and Year = '%s'",
mysql_real_escape_string($class),
mysql_real_escape_string($s),
mysql_real_escape_string($y)
);
// Result or die (print mysql error)
$result = mysql_query($SQL) or die( mysql_error() );
// Check if result has rows
if( mysql_numrows($result) > 0 )
{
$mbno_arr = array();
while ( $row = mysql_fetch_array($result) )
$mbno_arr[] = $row[0];
if( count($mbno_arr) > 0)
echo implode(',', $mbno_arr);
else
echo 'No number is there';
}
else
{
echo 'No result for query';
}
// free result
mysql_free_result($result);
NB use PDO or mysqli. mysql_* is deprecated
Firstly, mysql_* is now officially deprecated. Please use PDO or MySQLi.
Can you try this:
<?php
// Connect
$mysqli = new mysqli("localhost", "my_user", "my_password", "my_database");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
// Query
$query = "SELECT Fathers_Contact FROM student WHERE Class = ? AND Section = ? and Year = ?";
if ($stmt = $mysqli->prepare($query)) {
{
// Bind params
$stmt->bind_param("sss",
$class,
$s,
$y);
// Execute statement
$stmt->execute();
// fetch associative array
$mbno_arr = array();
$result = $stmt->fetch_result();
while ($row = $result->fetch_assoc())
{
// Build data
$mbno_arr[] = $row['Fathers_Contact'];
}
// close statement
$stmt->close();
// Debug?
$mbno_list = implode(',', $mbno_arr);
if (empty($mbno_list)) {
echo "No number is there";
} else {
echo "Query Results: $mbno_list";
}
}
// Close Connection
$mysqli->close();
?>

Pass a PHP variable to a MySQL query

What is wrong with this code? I get an empty array. I am passing a PHP variable to the query, but it doesn’t work; when I give a hardcoded value the query returns a result.
echo $sub1 = $examSubject[$i];
$subType = $examType[$i];
$query = $this->db->query("select dSubject_id from tbl_subject_details where dSubjectCode='$sub1'");
print_r($query->result_array());
Look up “SQL injection”.
I’m not familiar with $this->db->query; what database driver are you using? The syntax for escaping variables varies from driver to driver.
Here is a PDO example:
$preqry = "INSERT INTO mytable (id,name) VALUES (23,?)";
$stmt = $pdo->prepare($preqry);
$stmt->bindparam(1,$name);
$stmt->execute();
failing to see what you database abstraction layer ($this->db) does, here's the adjusted code from example1 from the mysql_fetch_assoc documentation
<?php
// replace as you see fit
$sub1 = 'CS1';
// replace localhost, mysql_user & mysql_password with the proper details
$conn = mysql_connect("localhost", "mysql_user", "mysql_password");
if (!$conn) {
echo "Unable to connect to DB: " . mysql_error();
exit;
}
if (!mysql_select_db("mydbname")) {
echo "Unable to select mydbname: " . mysql_error();
exit;
}
$sql = 'SELECT `dSubject_id` ';
$sql .= 'FROM `tbl_subject_details` ';
$sql .= "WHERE `dSubjectCode` ='$sub1';";
$result = mysql_query($sql);
if (!$result) {
echo "Could not successfully run query ($sql) from DB: " . mysql_error();
exit;
}
if (mysql_num_rows($result) == 0) {
echo "No rows found, nothing to print so am exiting";
exit;
}
while ($row = mysql_fetch_assoc($result)) {
echo $row['dSubject_id'];
}
mysql_free_result($result);
?>
Let me know what the output is, I'm guessing it will say: 6
Is it CodeIgniter framework you're using (from the $this->db->query statement). If so, why don't you try:
$this->db->where('dSubjectCode',$sub1);
$query = $this->db->get('tbl_subject_details');
If this doesn't work, you've got an error earlier in the code and $sub1 isn't what you expect it to be.

Categories