This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 2 years ago.
I am trying to build an application that detect if user's input(first 20 byte) exist on my database.
But I am stuck at sanitizing and making placeholder to it. Especially, this part $stmt->execute(), any advise and recommendation will be appreciated!
<?php
echo <<<_END
<form method='post' action='test.php' enctype='multipart/form-data' >
Tester: <input type='file' name='uploadfile'>
<input type='submit'>
</form>
_END;
if($_FILES){
require_once 'login.php';
if (!$conn) {
die(mysql_fatal_error());
}
$type = $_FILES['uploadfile']['type'];
if($type == "text/plain"){
$name = $_FILES['uploadfile']['name'];
$fh = fopen($name, 'r') or die("File Does not exist");
$content = file_get_contents($name, FALSE, NULL, 0, 20);
$content = sanitizeMySQL($conn, $content);
fclose($fh);
$stmt = $conn->prepare("SELECT * FROM storage WHERE mydata like ?");
$stmt->bind_param("s", $content);
$stmt->execute();
//$stmt->bind_result($content);
if (!$stmt) {
echo "Not Exist";
} else {
echo "Exist";
}
} else {
echo "txt only <br>";
}
}
This section of your code is already sanitising your input.
$stmt = $conn->prepare("SELECT * FROM storage WHERE mydata like ?");
$stmt->bind_param("s", $content);
$stmt->execute();
The first line lays out your sql query with parameters.
$stmt = $conn->prepare("SELECT * FROM storage WHERE mydata like ?");
The second line escapes any dangerous characters in the user input (i.e. in $content), and binds it to the position of the ? in your query in the line above.
$stmt->bind_param("s", $content);
The third line runs the query you created with the parameters you bound.
$stmt->execute();
An insecure method of doing this would look like this:
$stmt = $conn->prepare("SELECT * FROM storage WHERE mydata like '$content'");
If a user were to submit content which looked like this '; drop * from storage;//, then the resulting query would be:
SELECT * FROM storage WHERE mydata like ''; drop * from storage;//'
This would end up deleting all the data in your mydata table in your database.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
what i want to do is that it checks the input field and after that it will insert the following query or it it gives an error message. My problem is that my query won't insert.
My PHP function that won't work (other file then html file):
function Code($userID) {
require '../conn.php';
$sql = "SELECT `current_uses` FROM `sub_codes` WHERE `content` = '".$_POST['Code']."'";
$result = mysqli_query($conn, $sql);
$row = mysqli_fetch_array($result);
if ($row['current_uses'] > 0){
$query = "INSERT INTO `partner_subscriptions` (`id`, `user_id`, `sub_id`, `allowed_users`, `start_date`, `end_date`) VALUES (NULL, ?, ?, ?, ?, ?);";
$stmt = $conn->prepare($query);
$_userID = $userID;
$_subID = '99';
$_allowedUsers = '100';
$_startDate = date('Y-m-d');
$sql2 = "SELECT `end_date` FROM `sub_codes` WHERE `content` = '".$_POST['Code']."'";
$result2 = mysqli_query($conn, $sql2);
$row2 = mysqli_fetch_array($result2);
$_endDate = $row2['end_date'];
$stmt->bind_param("sssiiii", $_userID, $_subID, $_allowedUsers, $_startDate, $_endDate);
$stmt->execute();
$lastID = $conn->insert_id;
$stmt->close();
return $lastID;
}else {
echo "Wrong code";
}
}
My html file:
<br/><div class="form-group">
<label title="Required">Free description code:</label>
<input type="text" name="Code" class="form-control" id="Code"/>
</div><br/>
The rest of my PHP file (that i think you need to know):
if (usedmail($_POST['username'])==true) {
$lastID = saveUser($_POST['fnln'], $_POST['username'], password_hash($_POST['password'], PASSWORD_BCRYPT), 0, 0, 1);
$niv = NULL;
if ($_POST['type'] == "3") { // If the partner is an educational institution look for niveau
$niv = NivID($_POST['niv']);
}
Code($lastID, $_POST['Code']);
$path = saveImage();
Contact($lastID);
Image($lastID);
Social($lastID);
Story($lastID);
Skill($lastID);
$orgID = saveOrganisation($lastID, $_POST['organisation'], $path, $_POST['type'], $_POST['branche'], $niv);
updateUser($orgID, $lastID);
}
else {
header('Location: ../../mailerror');
}
every other function works normal except the code function and i don't really know why. I appreciate your help!
Well, for explanation reasons how to use mysqli the right way. First of all, you have to keep control of your code. Always check what happens and catch any mistakes. You don 't do that and that 's the reason you don 't know, why your insert statement is not executed.
Error Handling for the win!
Use the results, which are explained in detail in the manual. Nearly every mysqli method returns a false value, when something went wront. Use it!
$sql = "SELECT current_uses FROM sub_codes WHERE content = ?";
$stmt = mysqli_prepare($connection, $sql);
// Is there a prepared statement?
if (!$stmt) {
die(printf('Something went wrong: %s.', mysqli_error($connection)));
}
// use the mysqli statement (one type definition per used variable)
$result = mysqli_stmt_bind_param($stmt, "s", $_POST['code']);
if (!$result) {
die(printf('Something went wrong: %s.', mysqli_stmt_error($stmt)));
}
// execute the statement
$result = mysqli_stmt_execute($stmt);
if (!$result) {
die(printf('Something went wrong: %s.', mysqli_stmt_error($stmt)));
}
As you can see it is necessary to check what the result of each mysqli function call is to avoid unpredictable behavior of your script. Always keep in mind not to use post variables directly in sql statements. This is a huge mistake and opens your script for several vulnerabilities via sql injection.
Please read one of the many sql injection topics here on stack overflow to understand what sql injection is and how you can prevent it: How can I prevent SQL injection in PHP?
I had to change "sssiiii" to "iiiss" because Every single character of your 'sssiiii' stands for a single value that is bound to the statement.
How can I search for a name in my table if there is an apostrophe in the name?
If I insert name with an apostrophe like Ender's Game in my search box, it gives an error.
I already tried solutions provided on stackoverflow, but I am not able to solve this.
Here is my code:
$string1 = $_GET['name'];
$quer = "SELECT * FROM info WHERE name = '$string1'";
$q = mysqli_query($conn, $quer);
If there is an apostrophe in $_GET['name'], an error is shown.
How can I solve this?
Code in that form is vulnerable to SQL injection. Use mysqli::prepare instead:
$string1 = $_GET['name'];
$quer = "SELECT * FROM info WHERE name = ?";
$stmt = $conn->prepare($quer);
$stmt->bind_param('s', $string1);
$stmt->execute();
$stmt->bind_result($result);
$stmt->fetch();
$stmt->close();
var_export($result);
If you're adapting legacy, insecure code, it may be faster to use mysqli_real_escape_string. This should be reserved as a last resort, but it's there if you need it, and it's better than a regex.
The best practice that you can expect to hear over and over again from knowledgeable StackOverflow volunteers is to use prepared statements to ensure query security and reliability.
For your case, I recommend the following snippet which not only safely executes your SELECT query, but also provides informative diagnostic/debugging checkpoints throughout the process and allows you to process the resultset - represented by an multi-dimensional associative array.
$_GET['name'] = "vinay's name";
$string1 = $_GET['name'];
if (!$conn = new mysqli("host", "user", "pass", "db")) {
echo "Database Connection Error: " , $conn->connect_error; // do not show this to public
} elseif (!$stmt = $conn->prepare("SELECT * FROM info WHERE name = ?")) {
echo "Prepare Syntax Error: " , $conn->error; // do not show this to public
} elseif (!$stmt->bind_param("s", $string1) || !$stmt->execute()) {
echo "Statement Error: " , $stmt->error; // do not show this to public
}else{
$result = $stmt->get_result();
while($row = $result->fetch_array(MYSQLI_ASSOC)){
var_export($row); // do what you like here
}
}
It is important to note that using $stmt->bind_result($result) (like in Zenexer's answer) will not work (generates $result = NULL) if the info table contains more than one column (I assume it will work with one column, but I didn't test); and it will generate a Warning because of an imbalance between the number of selected columns from SELECT * and the number of nominated variables.
Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement
If you want to enjoy the benefits of explicitly binding a result variable, you should specify your desired columns in the SELECT clause like this:
if (!$conn = new mysqli("host", "user", "pass", "db")) {
echo "Database Connection Error: " , $conn->connect_error; // do not show this to public
} elseif (!$stmt = $conn->prepare("SELECT id FROM info WHERE name = ?")) {
echo "Prepare Syntax Error: " , $conn->error; // do not show this to public
} else {
if (!$stmt->bind_param("s", $string1) || !$stmt->execute() || !$stmt->bind_result($id)) {
echo "Statement Error: " , $stmt->error; // do not show this to public
} else {
while ($stmt->fetch()) {
echo "<div>$id</div>";
}
}
$stmt->close();
}
This question already has answers here:
PHP: Mysqli prepared statement with "select *"
(2 answers)
Closed 6 years ago.
Intro: I'm trying to do a sql-injection proof login on my website, so I'm using mysqli bind param, I've created the query following instructions from the official manual of php.net, unfortunately it doesn't work as expected.
Here is my query code:
//Asign post to variables
$var1 = $_POST["email"];
$var2 = $_POST["pwd"];
if(isset($_POST['submit'])){
//Query SQL
$sql = $mysqli->prepare("SELECT * FROM main WHERE email = ? AND pass = ?");
$sql->bind_param("ss", $var1, $var2);
$sql->execute();
$sql->bind_result($email, $pass, $license);
$sql->fetch();
echo $email;
echo $pass;
echo $license;
}
So, this piece of code should echo the three fields it fetched from my database but it doesn't return anything. My database connection is perfectly fine, because this query was working perfectly without any kind of bind_param.
Summing up, I want to know why it doesn't echo the 3 values i got from the Sql query (they show up as unexistent)
Edit My error was I was doinng "bind_result" instead of "get_rersult" which is much better if you are selecting everything (*)
Edit: sorry I didn't notice you are using mysqli connection
you can use get_result instead of bind_result
$sql = $mysqli->prepare("SELECT * FROM main WHERE email = ? AND pass = ?");
$sql->bind_param("ss", $var1, $var2);
$sql->execute();
$rows = $sql->get_result();
$row = $rows->fetch_assoc();
$email = $row['email'];
$pass = $row['pass'];
$license = $row['license'];
This question already has an answer here:
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 6 years ago.
I'm trying to execute the following query to update a record in a table.
require "conn.php";
$user_name = $_POST["username"];
$code = $_POST["code"];
$name = $_POST["groupname"];
echo "$user_name, $code, $name";
$sql_update = "UPDATE users SET group = '$name' WHERE username = '$user_name'";
if ($conn->query($sql_update) === TRUE) {
echo "success";
}
else {
echo "fail";
}
The query fails and I'm not sure why. The connection is made and I'm able to echo the username code and name. Is there a reason why it's not working?
Your code is not secure
Look at this code with prepared statements
require_once("conn.php");
$user_name = $conn->real_escape_string($_POST["username"]);
$code = $conn->real_escape_string($_POST["code"]);
$name = $conn->real_escape_string($_POST["groupname"]);
$sql_update = $conn->prepare("update `users` set `group` = ? where `username` = ?");
$sql_update->bind_param("ss",$name,$user_name);
$sql_update->execute();
$sql_update->close();
$conn->close();
And conn.php file should be like this
$config = parse_ini_file('config.ini'); // Connection infos.
$conn = mysqli_connect('localhost',$config['username'],$config['password'],$config['db_name']);
if($conn === false) {
die("Something was wrong ! Please try again later."); // Error if connection not ok.
}
$conn->set_charset("utf8");
Create file outside the public_html folder named config.ini to write connection data
[db_connection]
username = username
password = password
db_name = dbname
This function binds the parameters to the SQL query and tells the database what the parameters are. The "sss" argument lists the types of data that the parameters are. The s character tells mysql that the parameter is a string.
The argument may be one of four types:
i - integer
d - double
s - string
b - BLOB
Learn more here
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have this news system but I can't figure out how to do it like this: news.php?id=1 then it will output the news id 1. Please help.
I have this so far:
<?php
include_once('includes/config.php');
if($id != "") {
$id = mysql_real_escape_string($id);
$sql = mysql_query("SELECT * FROM news WHERE id = '$id'");
}
$res = mysql_query($sql);
while($row = mysql_fetch_assoc($res)){
if(isset($_GET['id']));
echo $res['body'];
}
?>
It connects to the database (details are stored in the config).
the parameters after the ? in the URL are GET items. Use this:
<?php
if (isset($_GET['id'])) {
$id = $_GET['id'];
// Rest of your code
}
<?php
include_once('includes/config.php');
// see if the id is set in the URL (news.php?id=)
if(isset($_GET['id'])) {
// get the ID from the URL
// to make it safer: strip any tags (if it's a number we could cast it to an integer)
$id = strip_tags($_GET['id']);
// don't use SELECT *, select only the fields you need
$sql = mysql_query("SELECT body FROM news WHERE id=".mysql_real_escape_string($id));
while($row = mysql_fetch_assoc($sql)) {
echo $res['body'];
}
} else {
echo 'please select an article';
}
I would recommend you get away from using the mysql functions and use mysqli instead, as mysql is depreciated and you'll have to learn mysqli or PDO anyway.
Edit: updated code per comments
Firstly lets dissect your current code, to see where your going wrong.
<?php
include_once('includes/config.php');
/*
$id is not set anywhere before its used so this if statement will not fire,
if you are attempting to get this $id from a url parameter then you need
to set it first from $_GET['id'] global
*/
if($id != "") {
$id = mysql_real_escape_string($id);
$sql = mysql_query("SELECT * FROM news WHERE id = '$id'");
}
/*
This piece of code will fire but where is $sql set?
The mysql_query() function expects a string containing your sql query
so the subsequent lines of code will fail because of this
*/
$res = mysql_query($sql);
while($row = mysql_fetch_assoc($res)){
//this block is in the wrong place
if(isset($_GET['id']));
echo $res['body'];
}
?>
The idea is to get the user input E.G the $_GET['id'] from the url first, check the value is what your looking for, and then build your query.
As the mysql_* functions are deprecated I will show you an example using PDO. Though you can use mysqli, BUT you must always use prepared query's whenever user values come into contact with your database. This is to stop nasty/accidental sql injections.
<?php
// make the connection to the database using PDO
try {
$db = new PDO('mysql:host=127.0.0.1;dbname=the_awsome_db', 'yourusername', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->exec("SET CHARACTER SET utf8");
} catch(PDOException $e) {
exit('Sorry there is a problem with the database connection :' . $e->getMessage());
}
// sanitize user input - expecting an int
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
if (is_numeric($id)) {
// now lets query the database with the param id from the user
// prepare the query, using a placeholder
$stmt = $db->prepare('SELECT body,
some_other_column
FROM news
WHERE id = :placeholder_id');
// bind the placeholder with the value from the user
$stmt->bindParam(':placeholder_id', $id);
// execute the prepared query
$stmt->execute();
// fetch the result
$result = $stmt->fetch(PDO::FETCH_ASSOC);
// result not empty - display
if (!empty($result)) {
// display your result, use print_r($result) to view the whole result set if unsure
echo $result['body'];
} else {
// no matching id found in the db, do something
echo 'No results found';
}
} else {
// do something as user input is not a number
exit(header('Location: ./index.php'));
}
?>
Hope it helps, if your unsure of getting parameters from the user you may need to look up some more tutorials and get the hang of that first before dabbling with databases and all that good stuff.