Can anyone help. I'm trying to shore up my security using mysql_real_escape_string on values passed to PHP for an internal messaging service, but I must be getting the syntax wrong somewhere because the values are not being inserted into the database. I've looked around for tutorials, help etc but struggling to get it right.
The code I'm using is below. The values that haven't been escaped ($email, $from, $time) are being entered correctly, but the other values are just entered blank.
<?php
session_start();
$conn = mysqli_connect('localhost', 'username', 'password', 'dbname');
$email=$_SESSION['email'];
$to = $_POST ['touser'];
$toemail = $_POST['touseremail'];
$from = $_SESSION['name'];
$message = $_POST['message'];
$subject = $_POST['subject'];
$time = time();
$query ="INSERT INTO messages
(to_user, to_email, subject, message, from_user, from_email, daterecord)
VALUES (
'" . mysql_real_escape_string($conn, $to) . "',
'" . mysql_real_escape_string($conn, $toemail) . "',
'" . mysql_real_escape_string($conn, $subject) . "',
'" . mysql_real_escape_string($conn, $message) . "',
'$from', '$email', '$time')";
$send = $conn -> query($query);
echo "Message sent!";
?>
check out the function mysqli_real_escape_string()
i should also note that the prefered method for escaping strings these days is parameter binding
You are using mysql_real_escape_string instead of mysqli_real_escape_string.
Fix that and it will work better!
The actual problem you're having is that you're mixing up between the mysql extension and the mysqli extension.
If you're using mysqli_connect(), then all the DB functions you use must begin mysqli_.
You're using mysql_real_escape_string, when the function you actually want is mysqli_real_escape_string.
That i is very important.
However, if you'll allow me to go beyond the actual problem described, I would recommend moving away from escaped queries, and instead use Parameterised Queries.
Parameterised Queries is a technique that allows you to specify queries like this:
SELECT fieldname from talbe WHERE arg = ? AND arg2 = ?
and then replace those ?s with your variables using mysqli_bind_param().
This technique is considered a much better technique than using escape strings.
Hope that helps.
Use the function mysqli_real_escape_string() instead
Doc: http://www.php.net/manual/en/mysqli.real-escape-string.php
Related
I'm a beginner when it comes to the topic. I've followed this tutorial to connect one form to a database and it worked well. Now I'd like to add another form and my questions are:
do I create separate function in connection.php?
do I create a separate table in the same database?
how do I generate a separate thank you message?
The other form is a contact form.
connection.php:
<?php
function Connect()
{
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "root";
$dbname = "responses";
// Create connection
$conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname) or die($conn->connect_error);
return $conn;
}
?>
thankyou.php
<?php
require 'connection.php';
$conn = Connect();
$email = $conn->real_escape_string($_POST['u_email']);
$query = "INSERT into newsletter (email) VALUES('" . $email . "')";
$success = $conn->query($query);
if (!$success) {
die("Couldn't enter data: ".$conn->error);
}
echo $_GET["form"];
echo "Thank you for subscribing to our newsletter. <br>";
$conn->close();
?>
The second form would look like this:
$name = $conn->real_escape_string($_POST['name']);
$email = $conn->real_escape_string($_POST['email']);
$message = $conn->real_escape_string($_POST['message']);
$query = "INSERT into contactForm (name,email,message) VALUES('" . $name . "','" . $email . "','" . $message . "')";
$success = $conn->query($query);
I've created two tables: newsletter and contactForm. Now, how do I direct form input to the right table?
1 - You can "require"/"include" the same connection.php wherever it suit you / need it
2 - you can create on the same Database a new table and do action on this new on your query example:
$query = "INSERT into newsletter (email) VALUES('" . $email . "')";
$success = $conn->query($query);
$query = "INSERT into newsletter_schedule (email,schedule_date) VALUES('" . $email . "', NOW())";
$success = $conn->query($query);
or you can create in a different db and change db name connected(more complex but sometimes needed)
3 - you can do in separate static file and redirect to using (PHP function)
header("location: tankyou.html");//put your file name/must be the first output, even a space before can throw a error
leave more details about the 3rd if is not what you are looking for
Unfortunately, your question, "How do I...?" is a bit broad in this case. Any number of ways. The only real way to get a sense for these things is to try a number of times. You may fail, but that's where the most learning happenings.
Your specific questions:
do I create separate function in connection.php?
Depends on what you need. I might include a 'CloseConnection' or 'TearDown' function, but doing so is not strictly necessary in PHP. (PHP does it's best to close down and stop using any resources you still have open at the end of your script.)
However, if you want to edge toward better practices, get in the habit now of always cleaning up after yourself. What you learned in kindergarten applies: if you opened it, close it. If you created it, dispose of it. If you allocated it, deallocate it. etc.
do I create a separate table in the same database?
Yes. This question is related to schema design, and again, you will just have to try things out and see what works for your situation and thought processes. You will know that things are not right when the logic gets really convoluted. But knowing that comes with nothing other than experience.
how do I generate a separate thank you message?
The same way you generate any other HTML. Some version of echo, print, or include/require. Given your current setup, I might create a separate function for this logic.
One thing which is not what you asked for, but which I feel compelled to point out: heavily consider prepared statements for your SQL, rather than string interpolation. That is ...
BAD:
$query = "INSERT into newsletter (email) VALUES('" . $email . "')";
$success = $conn->query($query);
BETTER/GOOD:
$sql = "INSERT INTO newsletter (email) VALUE ( ? )";
$statement = $conn->prepare( $sql );
$statement->bind_param('s', $email);
$statement->execute();
This is perhaps slightly more complicated, but also precludes any need for sanitization like real_escape_string.
For more information, read the documentation and google prepared statements, but the gist is this: for security reasons now, and higher performance later. By telling the database what will be coming, you preclude someone from injecting something you didn't expect or want.
I have a problem displaying my information in the database using phpmyadmin. I have 2 files (form.php and connect.php), it says it's connected to the database but nothing shows up in my database.
Is there any solution for that? I spent almost a whole day trying to resolve that.
Here's connect.php:
<?php
$mysql_host='localhost';
$mysql_user='root';
$mysql_password=''; **i don't have a password.
mysql_connect($mysql_host,$mysql_user,$mysql_password)
echo"connection sucess";
$link = mysqli_connect("localhost","root","") or die ("Couldn't not connect");
mysqli_select_db($link, "cooperative_db");
if (!$link) {
die('Could not connect: ' . mysql_error());
}
echo "Successfully connected \n";
$FIRST_NAME = $_POST['FIRST_NAME'];
$LAST_TIME = $_POST['LAST_NAME'];
$CIVIC_NUMBER = $_POST['CIVIC_NUMBER'];
$STREET = $_POST['STREET'];
$CITY = $_POST['CITY'];
$PROVINCE = $_POST['PROVINCE'];
$POSTAL_CODE = $_POST['POSTAL_CODE'];
$COUNTRY = $_POST['COUNTRY'];
//$TELEPHONE = $_POST['TELEPHONE'] . $_POST['TELEPHONE'] . $_POST['TELEPHONE'];
$INCOME = $_POST['INCOME'];
//$INCOME_SOURCE = $_POST['element_6_1'] . $_POST['element_6_2'] . $_POST['element_6_3'] . $_POST['element_6_4'] .
//$_POST['element_6_5'];
$sql = "INSERT INTO candidat(FIRST_NAME, LAST_NAME, CIVIC_NUMBER, STREET, CITY, PROVINCE, POSTAL_CODE, COUNTRY, INCOME) VALUES ('$FIRST_NAME', '$LAST_TIME', '$CIVIC_NUMBER', '$STREET','$CITY', '$PROVINCE', '$POSTAL_CODE', '$COUNTRY', '$INCOME')";
?>
It seems like you may have many issues in your code. Let's start step by step.
I am not sure if that: "**i don't have a password." is actually inside your code, so change it first of all to //i don't have a password..
Now, in the second picture you showed us, it only echo 1 line instead of two, and inside your code you actually have two lines that should echo a result.
echo"connection sucess"; and echo "Successfully connected \n";
This could be due to the fact that you forgot a ; in the line right before the first echo.
mysql_connect($mysql_host,$mysql_user,$mysql_password);
May I ask you why are you using both mysql, and mysqli? If it's just for testing, there's no harm in it, plus you should know that mysql is deprecated and no longer supported or updated, you better just use mysqli, please refer to this post Why shouldn't I use mysql_* functions in PHP?.
The first picture shows that you don't have a table named candidat, yet in your code you have this: INSERT INTO candidat. Maybe you wanted this to be INSERT INTO cooperative_table instead?
Please make those small fixes, and tell us your result.
Edit: I forgot to mention, just like tadman commented, you better be aware of the SQL Injection bugs you have and fix them accordingly.
Have some problem I couldn't find solution for, though searched through many sources (and questions here too). So, here it is.
With the PHP-code below I suppose to collect data from a HTML-form and send it to a local WAMP-server. But, though final check shows me "Success!", no new rows in the database's table are found, it stays empty. Names are correct, commands are (as I see it) too, so I just don't know what's wrong.
I hope you guys could help me. ^^
//Check if user submited a form
if (isset($_POST['submit'])) {
//Check if from is properly filled
if (empty($_POST['itemName']) || empty($_POST['itemPic']) || empty($_POST['itemPrice']) || empty($_POST['itemProvider'])) {
echo '<script>alert ("Fill out the form please!")</script>';
} else {
$conn = new mysqli('localhost:3306', 'root', '', 'goods-review');
//Check if connection established
if (mysqli_connect_errno()) {
exit('Connect failed: ' . mysqli_connect_error());
}
//Sending data
$newItem = array('itemName' => $_POST['itemName'], 'itemPic' => $_POST['itemPic'], 'itemPrice' => $_POST['itemPrice'], 'itemProvider' => $_POST['itemProvider']);
$sql = "INSERT INTO goods (itemName, itemPic, itemPrice, itemDate, itemProvider) VALUES ('" . $newItem['itemName'] . "', '" . $newItem['itemPic'] . "', '" . $newItem['itemPrice'] . "', date('Y:m:d, H:i:s'), '" . $newItem['itemProvider'] . "')";
//Check if sent
if ($sql) {
echo '<script>alert ("Success!")</script>';
} else {
echo '<script>alert ("Error!")</script>';
}
$conn->close();
}
}
The code is just assigning a string value to a variable.
$sql = "INSERT ...";
And the string value is not submitted to the database; it's not being executed as a SQL statement. There's nothing magical about the name of the variable. As far as PHP is concerned, the code is just assigning a value to a variable. That's it.
If you want to execute a SQL statement, you need to add code that actually does that. It shouldn't be difficult to find an example of how to do that.
IMPORTANT NOTE: The code in the question appears to create a SQL statement that is vulnerable to SQL Injection. A much better pattern is to use prepared statements with bind placeholders.
Reference: mysqli_prepare
If there's some (unfathomable) reason that you can't use prepared statements, then at a minimum, any potentially unsafe values that are included in the SQL text must be properly escaped.
Reference: mysqli_escape_string
If you have setup the $newItem array first.
Normaly you will validate the user-input and ensure that the user-input has no SQL injections in it.
Read here about it: What is SQL injection?
After that
(You have to add $newItem['itemDate']=date('Y:m:d, H:i:s');)
$sql = "INSERT INTO goods (".implode(', ',array_keys($newItem)).")"
." VALUES ('".implode("', '",$newItem)."')";
if (mysqli_query($conn,$sql)){
echo '<script>alert ("Success!")</script>';
} else {
echo '<script>alert ("Error!")</script>';
}
If you are using this:
you dont have too keep an eye on the right field order
every field value becomes ' around them
you have less code to write
field count and order can change
Finally mysqli_query() returns FALSE if nothing is insert and you can check for that.
Sidenote: Try to use OOP Version of the MYSQLi Extention and Prepared Statments. Read about it here: mysqli, OOP vs Procedural
<?php
mysql_connect("mysql6.000webhost.com","a6124751_murali1","***");
$db= mysql_select_db("a6124751_signup");
$topic=$_GET["Topic"];
$question=$_GET["Question"];
$company =$_GET["Company"];
$query = "INSERT INTO questions (topic, question, company) VALUES ($topic, $question, $company)";
$sql1=mysql_query($query);
if (!$sql1) {
die('Invalid query: ' . mysql_error());
}
?>
this is my php code in server where there is a table named 'questions' and i am trying to insert the data into it from the input got from the GET method using form at front end, i can figure out that data is coming properly from the client which i have checked using echo. I am getting an error as
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'name, type your question here, company)' at line 1
Don't know what is the error in the query. anyone find it out asap. thank you
You need to quote your values
('$topic', '$question', '$company')
since those are strings.
Plus, you should escape your data for a few reasons. Not let MySQL complain about certain characters such as hyphens etc., and to protect against SQL injection.
Use prepared statements:
https://en.wikipedia.org/wiki/Prepared_statement
Reference(s):
https://en.wikipedia.org/wiki/SQL_injection
How can I prevent SQL injection in PHP?
http://php.net/manual/en/function.mysql-real-escape-string.php
Edit:
As an example using your present MySQL API:
$topic = mysql_real_escape_string($_GET['topic']);
$question = mysql_real_escape_string($_GET['question']);
$company = mysql_real_escape_string($_GET['company']);
I don't know what your inputs are called, so that's just an example.
You mentioned about using $_GET for debugging but using a POST method.
Change all $_GET to $_POST above.
Try this
<?php
$db = mysqli_connect('mysql6.000webhost.com', 'a6124751_murali1', 'default#123', 'a6124751_signup');
if (!$db) {
die('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
$topic = $_GET["Topic"];
$question = $_GET["Question"];
$company = $_GET["Company"];
$query = "INSERT INTO questions (topic, question, company) VALUES ('$topic', '$question', '$company')";
$sql1=mysqli_query($db, $query);
if(!$sql1)
{
die('Invalid query: ' . mysqli_error($db));
}
?>
Fixes in your code
The mysql extension is deprecated and will be removed in the future:
use mysqli or PDO instead
You need to quote your values ('$topic', '$question', '$company')
You have to put the values in single qoutes, if that are char types:
$query = "INSERT INTO questions (topic, question, company) VALUES ('$topic', '$question', '$company')";
But you should not longer use the deprecated mysql_*API. Use mysqli_* or PDO with prepared statements.
I am having trouble making this seemingly simple MySql query work. Can anyone spot the problem?
<?php
include "config.php";
$offerid = $_POST["offerid"];
$ip = $_SERVER["REMOTE_ADDR"];
mysql_query("INSERT INTO voted (offerid,ip) VALUES (".$offerid.",".$ip.")");
?>
You probably want some single quotes:
"INSERT INTO voted (offerid,ip) VALUES ('" . $offerid . "','" . $ip . "')"
You should also use intval and mysql_real_escape_string to avoid SQL injection vulnerabilities:
$sql = "INSERT INTO voted (offerid,ip) VALUES (" .
intval($offerid). ", '" .
mysql_real_escape_string($ip) . "')";
Another alternative which may be easier to read is to use sprintf:
$sql = sprintf("INSERT INTO voted (offerid, ip) VALUES (%d, '%s')",
$offerid, mysql_real_escape_string($ip));
To place a string value into query, you must perform 2 actions on it:
enclose it in quotes
and escape special characters.
So, query must be like this:
INSERT INTO voted (text) VALUES ('I\'m a programmer')
Armed with this knowledge, you can easily write a code to make valid query:
$offerid = mysql_real_escape_string($_POST["offerid"]);
$ip = mysql_real_escape_string($_SERVER["REMOTE_ADDR"]);
$sql = "INSERT INTO voted (offerid,ip) VALUES ('$offerid','$ip')"
mysql_query($sql) or trigger_error(mysql_error().$sql);
Note the trigger_error part.
It will provide you with comprehensive information on any error
my guess would be with quotes
mysql_query("INSERT INTO voted (offerid,ip) VALUES (\"".$offerid."\",\"".$ip."\")");
<?php
include "config.php";
$offerid = $_POST["offerid"];
$ip = $_SERVER["REMOTE_ADDR"];
mysql_query("INSERT INTO voted (offerid,ip) VALUES ('".mysql_real_escape_string ($offerid)."','".mysql_real_escape_string ($ip)."')");
?>
This adds the single quote marks around the strings you are inserting - as well as mysql_real_escape_string php function that will escape (add a backslash infront of) any security risk characters.
In addition to using intval(...) and mysql_real_escape_string(...) you could use parameterized statements (or placeholders) using PEAR::DB or PEAR::MDB2:
$dsn = "mysqli://testuser:testpass#localhost/test";
$conn =& DB::connect ($dsn); // using PEAR::DB, though it's been superseded
if (DB::isError ($conn)) {
die ("Cannot connect: " . $conn->getMessage () . "\n");
}
$result =& $conn->query ("INSERT INTO voted (offerid,ip) VALUES (?,?)", array($_POST["offerid"], $_SERVER["REMOTE_ADDR"]));
if (DB::isError ($result)) {
die ("INSERT failed: " . $result->getMessage () . "\n");
}
Using placeholders and parameters is pretty common on platforms other than PHP, so it's not a bad idea to understand the basic premise behind them.
If you're interested in using DB modules like these, I'd recommend checking out Writing Scripts with PHP's PEAR DB Module by Paul DuBois. Again, the module it describes is superseded, but I find it's nonetheless interesting and informative.