does the following piece of code face sql injection problems? IF so why and what could be changed to prevent it?
$sql2 = "UPDATE Candidates SET ".$row['Field']."= '$_POST[$tempname]' WHERE ID='".$_GET["id"]."'";
$result2 = mysqli_query($con,$sql2);
if ($con->query($sql2) === TRUE) {
if($_POST['Status']=="Employed"){
$sql3 = "INSERT INTO Employees (AFNumber, CID, Status, Name, DateOfBirth,DateOfEmployment)
VALUES ('".$_POST['AFNumber']."', '".$_POST['ID']."', 'Employed', '".$_POST['FullNameEng']."','".$_POST['DoBasID']."', '".date('d/m/Y')."')";
$result3 = mysqli_query($con,$sql3);
if ($con->query($sql3) === TRUE) {
}else {
echo "Error: " . $sql3 . "<br>" . $con->error;}
echo '<script>swal("Error", "Something went wrong '.$con->error.'", "error");</script>';
}
} else {
echo "Error: " . $sql2 . "<br>" . $con->error;
echo '<script>swal("Error", "Something went wrong '.$con->error.'", "error");</script>';
}
$row['Field'] = "`{$row['Field']}`"; //its better to use ` around field names. there can be 'date', 'begin', 'column' or other reserved keywords http://dev.mysql.com/doc/refman/5.6/en/keywords.html
$_POST[$tempname] = mysqli_real_escape_string($con, $_POST[$tempname]); //have no idea which data type your $row['Field']-column, so lets rely on escaping will be enough http://php.net/manual/en/mysqli.real-escape-string.php
$_GET['id'] = (int)$_GET['id']; //i believe that your `id` is an integer, otherwise you should use mysqli_real_escape_string
$sql2 = "UPDATE Candidates SET ".$row['Field']." = '{$_POST[$tempname]}' WHERE `ID` = '{$_GET['id']}'";
$result2 = mysqli_query($con, $sql2);
if ($con->query($sql2) === TRUE) {
if($_POST['Status']=="Employed") {
$_POST['AFNumber'] = (int)$_POST['AFNumber']; //i believe that your `AFNumber` is an integer, otherwise you should use mysqli_real_escape_string
$_POST['ID'] = (int)$_POST['ID']; //i believe that your `CID` is an integer, otherwise you should use mysqli_real_escape_string
$_POST['FullNameEng'] = mysqli_real_escape_string($con, $_POST['FullNameEng']);
$_POST['DoBasID'] = mysqli_real_escape_string($con, $_POST['DoBasID']); //if DateOfBirth is not a string - u can use (int) instead
$sql3 = "
INSERT INTO Employees
(AFNumber, CID, Status, Name, DateOfBirth, DateOfEmployment)
VALUES
('".$_POST['AFNumber']."', '".$_POST['ID']."', 'Employed', '".$_POST['FullNameEng']."', '".$_POST['DoBasID']."', '".date('d/m/Y')."')
";
//...
The main idea here (also the simplest, minimal) is:
1) if data-type is integer use (int) or intval() on incoming values.
2) if data-type is integer unsingned use abs() on incoming values.
3) othervise (on strings) use mysqli_real_escape_string
Read about Escape Sequences https://dev.mysql.com/doc/refman/5.0/en/string-literals.html
For future read about Prepared Statements https://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html
Related
I have an auto incrementing ID called deviceID in one of my fields. I was wanting to pass this to a session in php to use later on and was planning on using scope_identity() as I understand that this is the best way to get the current Primary key ID. However anytime I have attempted to use it I have had a error message saying that it is an undefined function. Here is my code so without the scope_identity():
<?php
session_start();
include 'db.php';
$screenWidth = $_POST['screenWidth'];
$screenHeight = $_POST['screenHeight'];
$HandUsed = $_POST['HandUsed'];
$_SESSION["screenWidth"] = $screenWidth;
$_SESSION["screenHeight"] = $screenHeight;
if (isset($_POST['submit'])) {
$screenWidth = $_POST['screenWidth'];
$screenHeight = $_POST['screenHeight'];
$phoneType = $_POST['phoneName'];
$HandUsed = $_POST['HandUsed'];
$_SESSION["HandUsed"] = $HandUsed;
$_SESSION["phoneName"] = $phoneType;
echo 'hello';
$sql = "
INSERT INTO DeviceInfo (DeviceID, screenWidth, phoneType, screenHeight, HandUsed)
VALUES ('$screenWidth','$phoneType', '$screenHeight', '$HandUsed')
SELECT SCOPE_IDENTITY() as DeviceID
";
if (sqlsrv_query($conn, $sql)) {
echo ($sql);
echo "New record has been added successfully !";
} else {
echo "Error: " . $sql . ":-" . sqlsrv_errors($conn);
}
sqlsrv_close($conn);
}
?>
You need to fix some issues in your code:
The INSERT statement is wrong - you have five columns, but only four values in this statement. I assume, that DeviceID is an identity column, so remove this column from the column list.
Use parameteres in your statement. Function sqlsrv_query() does both statement preparation and statement execution, and can be used to execute parameterized queries.
Use SET NOCOUNT ON as first line in your statement to prevent SQL Server from passing the count of rows affected as part of the result set.
SCOPE_IDENTITY() is used correctly and it should return the expected ID. Of course, depending on the requirements, you may use IDENT_CURRENT().
The following example (based on the code in the question) is a working solution:
<?php
session_start();
include 'db.php';
if (isset($_POST['submit'])) {
$screenWidth = $_POST['screenWidth'];
$phoneType = $_POST['phoneName'];
$screenHeight = $_POST['screenHeight'];
$HandUsed = $_POST['HandUsed'];
$params = array($screenWidth, $phoneType, $screenHeight, $HandUsed);
$sql = "
SET NOCOUNT ON
INSERT INTO DeviceInfo (screenWidth, phoneType, screenHeight, HandUsed)
VALUES (?, ?, ?, ?)
SELECT SCOPE_IDENTITY() AS DeviceID
";
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
echo "Error: " . $sql . ": " . print_r(sqlsrv_errors());
exit;
}
echo "New record has been added successfully !";
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
echo $row["DeviceID"];
}
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
}
?>
I'm making an Android app that connects to a database online and lets the user edit the database from the application, I'm new to PHP and MySql but from my research I think I should be using an UPDATE statement, I've written the code below to register new users on the site from a tutorial, but I'd like to change the INSERT statement to an UPDATE statement so that instead of registering a new user, the App updates existing data that I have entered in PHPMYADMIN, could someone show me how to do this? Also, if you require the code for the app mention it in the comments and I'll add it to the question, I don't want to post too much unneccessary code. Thanks in advance.
<?php
require "conn.php";
$patient_name = $_POST["patient_name"];
$check_in_date = $_POST["check_in_date"];
$room_number = $_POST["room_number"];
$bed_number = $_POST["bed_number"];
$notes = $_POST["notes"];
$mysql_qry = "insert into patients(patient_name, check_in_date, room_number, bed_number, notes) values ('$patient_name', '$check_in_date', '$room_number', '$bed_number', '$notes')";
if($conn->query($mysql_qry) === TRUE) {
echo "Insert successful";
}
else{
echo "Error: " . $mysql_qry . "<br>" . $conn->error;
}
$conn->close();
?>
EDIT
The fixed code is below, it now updates records already in the database rather than adding new data.
<?php
require "conn.php";
$patient_name = $_POST["patient_name"];
$check_in_date = $_POST["check_in_date"];
$room_number = $_POST["room_number"];
$bed_number = $_POST["bed_number"];
$notes = $_POST["notes"];
$mysql_qry = "UPDATE patients SET notes='$notes' WHERE patient_name='$patient_name'";
if($conn->query($mysql_qry) === TRUE) {
echo "Insert successful";
}
else{
echo "Error: " . $mysql_qry . "<br>" . $conn->error;
}
$conn->close();
?>
first of all this PHP code is vulnerable to sql injection you should, no need to update your code to use either mysqli prepared statement or PDO prepared statement
secondly the easiest way I know you accomplish your goal would make a unique constraint on some columns and then use a mysql feature ON DUPLICATE UPDATE
for this example I'll assume that the unique fields determining an update instead of an insert are patient_name, check_in_date, room_number, and bed_number (in case john smith was in the same room as john smith in seprate beds) the query to update the table would be like this
ALTER TABLE `patients` ADD UNIQUE `unique_index`(`patient_name`, `check_in_date`, `room_number`, `bed_number`);
so now to address the sql injection bit and the query, I'll update the example to use mysqli statement and will assume patient_name and notes are strings (varchar/nvarchar), room_number and bed_number are integers, and check_in_date is a date
Edit My original answer had a syntax error in the query and also passing variables to the prepared statement below is the updated answer
$mysqliConn = new mysqli("localhost", "my_user", "my_password", "mydatabase");
$stmt = $mysqliConn->prepare("insert into patients
(patient_name, check_in_date, room_number, bed_number, notes)
values (?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE notes=values(notes)");
$patient_name = $_POST["patient_name"];
$check_in_date = $_POST["check_in_date"];
$room_number = $_POST["room_number"];
$bed_number = $_POST["bed_number"];
$notes = $_POST["notes"];
mysqli_stmt_bind_param($stmt, "sdiis",
$patient_name, $check_in_date, $room_number, $bed_number, $notes);
hope this helps
Edit
Regarding the unique key, a unique key means that all fields in the unique key have to be unique when combined so for the example above
if record 1 is
patient_name, check_in_date, room_number, bed_number, notes
'john smith', '3/1/2017' , 413 , 2 , 'patient is sick'
and record two is
'jane doe' , '3/1/2017' , 413 , 2 , 'patient has wound'
these two records will note be duplicates with the above constraint but if you do need to change the constraint you can do the following
DROP the Constraint
ALTER TABLE `patients` DROP INDEX `unique_index`;
Then recreate the constraint like this
ALTER TABLE `patients` ADD UNIQUE `unique_index`(`patient_name`, `check_in_date`, `room_number`);
also if you named your constraint something other than unique_index you can find the key_name by running the following
SHOW INDEX FROM `patients`;
the name will be in the key_name column
additionally you may want to alter the last line of the query to be this in your php if you change the unique constraint so you can change bed number
ON DUPLICATE KEY UPDATE bed_number=values(bed_number), notes=values(notes)
You can also use REPLACE INTO, then you don't have to change the SQL statement. Let MySQL do the work for you.
https://dev.mysql.com/doc/refman/5.7/en/replace.html
<?php
require "conn.php";
$patient_name = $_POST["patient_name"];
$check_in_date = $_POST["check_in_date"];
$room_number = $_POST["room_number"];
$bed_number = $_POST["bed_number"];
$notes = $_POST["notes"];
$mysql_qry = "REPLACE INTO patients(patient_name, check_in_date, room_number, bed_number, notes) VALUES ('$patient_name', '$check_in_date', '$room_number', '$bed_number', '$notes')";
if($conn->query($mysql_qry) === TRUE) {
echo "Insert successful";
}
else{
echo "Error: " . $mysql_qry . "<br>" . $conn->error;
}
$conn->close();
Also, you should really take a look at using PDO with prepared statements and parameters.
https://secure.php.net/manual/en/pdo.prepare.php
Actually I was looking for a small function that converts an INSERT MySQL query to an UPDATE query. So maybe other people were looking for the same and I think this is what the original poster was looking for aswell... I couldnt find any so I made this simple function which works for my needs, ofcourse you will have to make sure your original query is safe from MySQL injection.
It will convert
INSERT INTO aaa (bbb, ccc) VALUES ('111', '222')
to
UPDATE aaa SET ccc='222' WHERE bbb='111'
Use the 2nd variable ($iColumn) to identify the WHERE statement.
function convertInsertToUpdate($sQuery, $iColumn = 1) {
$sNewQuery = "";
$iPos = strpos($sQuery, ' (');
$sTmpTable = substr($sQuery, 0, $iPos);
$iPos = strpos($sTmpTable, 'INSERT INTO ');
$sTmpTable = substr($sTmpTable, $iPos+12);
$iPos = strpos($sQuery, ') VALUES (');
$sTmpValues = substr($sQuery, $iPos+10);
$iPos = strrpos($sTmpValues, ')');
$sTmpValues = substr($sTmpValues, 0, $iPos);
$iPos = strpos($sQuery, '(');
$sTmpColumns = substr($sQuery, $iPos+1);
$iPos = strpos($sTmpColumns, ') VALUES (');
$sTmpColumns = substr($sTmpColumns, 0, $iPos);
$aColumns = explode(', ', $sTmpColumns);
$aValues = explode(', ', $sTmpValues);
if (count($aColumns)>0 && count($aColumns) == count($aValues) && $iColumn < (count($aValues)+1)) {
$sNewQuery = "UPDATE ".$sTmpTable." SET";
$sTmpWhere = "";
$bNotFirst = false;
$iX = 0;
while ($iX<count($aColumns)) {
if ($iColumn == ($iX+1)) {
$sTmpWhere = " WHERE ". $aColumns[$iX]."=".$aValues[$iX];
$iX++;
continue;
}
if ($bNotFirst) {
$sNewQuery .= ",";
}
$sNewQuery .= " ".$aColumns[$iX]."=".$aValues[$iX];
$bNotFirst = true;
$iX++;
}
$sNewQuery .= $sTmpWhere;
}
return $sNewQuery;
}
This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Closed 6 years ago.
Im trying to take input from a form, then check table (user) if that name exsits and I need to grab the uid colum.
Input (username / MSG) > Check for username > if so get uid > else add user(This I got) > take uid and use when i INSERT the msg into its table (message)
Table structure:
user: uid (Unique) | name
Heres where in at PHP whise:
<?php
$name = $_GET["name"];
$message = $_GET["message"];
$checkn = "SELECT 1 FROM user WHERE name = $name";
$sql = "INSERT INTO user (uid, name) VALUES ('','$name')";
$msg = "INSERT INTO message (uid, message) VALUES ('$uid','$message')";
$uid = "SELECT uid FROM user WHERE name = $name";
$result = $conn->query($checkn);
if ($conn->query($checkn) === TRUE) {
echo "Checkn TRUE";
}else {
echo "<br> SHEEET" . $checkn . $conn->error;
}
$conn->close();?>
I erased the bulk to start over and get this fixed so once I can get this portion done I have the add if user doesn't exist. Thank you.
I think You are writing the query wrong, when using PHP you should write the query inside ' if it contains variable. " won't parse the variable value.
Replace :
$checkn = "SELECT 1 FROM user WHERE name = $name";
With:
$checkn = 'SELECT 1 FROM user WHERE name = $name';
And it should work. Do the same with other queries too. Use ' instead of "
Hope it helps.
Just from the top of my head
<?php
$name = $_GET["name"];
$message = $_GET["message"];
$checkn = sprintf('SELECT 1 FROM `user` WHERE `name` = \'%s\'', $name);
$sql = sprintf('INSERT INTO `user` (`uid`, `name`) VALUES (\'\',\'%s\')', $name);
$msg = sprintf('INSERT INTO `message` (`uid`, `message`) VALUES (\'%s\',\'%s\')', $uid, $message);
$uid = sprintf('SELECT `uid` FROM `user` WHERE `name` = \'%s\'', $name);
$result = $conn->query($checkn);
if ($conn->query($checkn) == TRUE) {
echo "Checkn TRUE";
} else {
echo "<br> SHEEET" . $checkn . $conn->error;
}
$conn->close();
?>
for some reason i have sometimes had problems when i did not put ` around table names.
I have also separated the variable interpolation so it makes it easier to secure it for sql injection (i did not secure it).
You used triple === this means its strict but mysql would pass 1 back which when using strict is not true.
Hope it helps
I want to GET user id FROM players WHERE username='$username' and post it into another MySQLi query and post it as pid but it shows error somehow, did I miss something?
if(isset($_POST["add"])) {
$content = $_POST['content'];
$sql = "SELECT id FROM players WHERE username='$username'";
$sql1 = "INSERT INTO bulletinboard (pid,content) VALUES ('$sql','$content')";
if (mysqli_query($conn, $sql1)) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
}
This is the error I am receiving.
Error: SELECT id FROM players WHERE username='nasty93'
Thanks
You need to execute the query so it needs to not be quoted. You also should familiarize yourself with the insert...select syntax. http://dev.mysql.com/doc/refman/5.7/en/insert-select.html
You also should use parameterized queries. Here it is altered (untested) (I also only use mysqli on SO so likely to be an error here).
if(isset($_POST["add"])) {
$content = $_POST['content'];
$sql1 = "INSERT INTO bulletinboard (pid,content) SELECT id, ? FROM players WHERE username=?";
$stmt = mysqli_prepare($conn, $sql1) or die(mysqli_error($conn));
mysqli_stmt_bind_param($stmt, "ss", $content, $username) or die(mysqli_error($conn));
mysqli_stmt_execute($stmt) or die(mysqli_error($conn));
}
I'm trying to retrieve the last id number inserted with mysql_insert_id() but always return 0, my id field is auto increment so I don't know why it returns 0 thanks. please help
include 'C:\xampp\htdocs\Student_evaluation\functions.php';
if(!loggedin())
{
header("Location: http://localhost/dev/userarea.php");
exit();
}
if(isset($_POST['submit']))
{
//get data
$name = $_POST['name'];
$f_lastname = $_POST['f_lastname'];
$second_lastname = $_POST['second_lastname'];
$student_number = $_POST['student_number'];
$semester_year = $_POST['semester_year'];
$course = $_POST['course'];
$section = $_POST['section'];
$grade = $_POST['grade'];
$student_perform = $_POST['student_perform'];
$comment_box = $_POST['comment_box'];
$sql = "INSERT INTO `students`(`name`, `first_lastname`, `second_lastname`, `numero_estudiante`, `semester`, `course`, `section`, `f_grade`, `students_perform`, `comments`)
VALUES ('$name','$f_lastname','$second_lastname','$student_number','$semester_year','$course','$section','$grade','$student_perform','$comment_box')";
$con = mysqli_connect("localhost","root","","rememberme");
$result = mysqli_query($con, $sql);
echo "ID of last inserted record is: " . mysql_insert_id();
}
You're using one library (mysqli) to perform the query, then another (mysql) to obtain the auto-increment ID. That can't work. Among other issues, you haven't even connected to the database with the second library!
Consistently use mysqli or, better yet, PDO, which will help you plug your blinding security flaw.
You should do something like this (using mysqli_insert_id):
$con = mysqli_connect("localhost","root","","rememberme");
$sql = "INSERT INTO ...";
$result = mysqli_query($con, $sql);
echo "ID of last inserted record is: " . mysqli_insert_id($con);
mysql_insert_id and mysqli_insert_id are both different and you are using mysqli so use mysqli_insert_id instead of mysql_insert_id and it's better to use mysqli instead of mysql.