OK guys, I'm having trouble with mysql_real_escape_string. It is a simple POST table with title and contents, which should in theory work fine (by me).
$db = new mysqli('...','...','...','...') or die ('error with connection');
$db->set_charset('utf8');
$title = trim($_POST['title']);
$contents = trim($_POST['contents']);
$title = mysql_real_escape_string($title);
$contents = mysql_real_escape_string($contents);
$sql = "INSERT INTO posts SET title = '$title', contents = '$contents'";
$query = $db->query($sql);
I found when I place 'echo' before and after 'mysql_escape_string' like:
echo 'before' . $title;
$title = mysql_real_escape_string($title);
echo 'after' . $title;
that it echoes the title on the "before" line, but on the "after" line it echoes blank $title.
Note: whan I use 'mysql_escape_string' instead (of real), it works fine (but I guess this is weaker protection).
Any ideas??
Thank you.
The reason title is empty is because mysql_real_escape_string is returning FALSE.
This happened because it requires a MySQL connection to the database, you have MySQLi. From the docs,
A MySQL connection is required before using mysql_real_escape_string() otherwise an error of level E_WARNING is generated, and FALSE is returned
The way to fix the issue is to use mysqli_real_escape_string to match your database connection, as suggested in the other answers. Obviously for security, you're better off using prepared statements.
Also, the database link needs to be supplied. Since you're using the OO style, this is done as
$db = new mysqli()
$title = $db->real_escape_string($title)
mysql_real_escape_string() works in context of connection made by "mysql" extension, but you use "mysqli".
You need to either connect using mysql_connect() not recommended
Or you need to use new approaches from mysqli such as prepared statements or mysqli_real_escape_string()
You should not interpolate user-generated strings into sql. Use prepared statements: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
In your case:
$db = new mysqli('...','...','...','...') or die ('error with connection');
$db->set_charset('utf8');
$title = trim($_POST['title']);
$contents = trim($_POST['contents']);
$sql = $db->prepare("INSERT INTO posts (title, contents) VALUES (?,?)");
$sql->bind_param('ss', $title, $contents);
$sql->execute();
Related
<?php
$host_name = '***';
$database = '***';
$user_name = '***';
$password = '***';
$link = mysqli_connect($host_name, $user_name, $password, $database);
$con = $_POST['User_ID'];
echo "Se ha ascendido al usuario $con";
$meta= 'a:1:{s:13:"administrator";b:1;}';
$consulta = 'UPDATE ***usermeta
SET
meta_value = $meta
WHERE
User_ID=$con and meta_key = "***capabilities"';
mysqli_query($link, $consulta);
echo "<br><br><br><a href='***'>Volver</a>";
In this code im trying to update an specific column from a table but it just wont work, it appears like it is working but when i go into phpmyadmin the data wont update, here is some info to keep in mind:
mysqli_connect works
query works when i execute it on phpmyadmin
i can do other queries (select) that works
data is correctly received by POST method
those " from variable $meta have to stay
I honestly dont have any idea of what is causing the code to just not work, not a single syntax error displayed or anything else. At first i thought it had something to do with the quote marks but now i dismissed that posibility.
Any help?
There's a catalog of issues here.
Your update statement is wrapped in single quotes - so your variables will not be substituted.
You've used double quotes as a delimiters for strings inside the query - that's not supported by SQL - they should be single quotes.
Table names cannot cannot contain asterisk characters.
That you are not seeing "a single syntax error" is a major issue - the DBMS will be screaming for help when it sees this.
Embedding composite data (json) in a scalar value is just asking for trouble.
Your code is vulnerable to SQL injection.
Whenever your thread of execution leaves PHP (in your code, when you call mysqli_conect() and mysqli_query()) you should be explicitly checking the result of the operation.
For one, you should have some kind of error handling so you know what the problem is. Secondly, you're calling mysqli_query directly instead of using it as a method from your already instantiated class $link.
Also, you really should be using back-ticks for column names and single quotes for column values.
Lastly, you need to escape certain special characters using mysqli_real_escape_string. Alternatively, you could use prepared statements, but I'll keep it simple. Instead of prepared statements, you can use PHP's sprintf function.
<?php
$host_name = '***';
$database = '***';
$user_name = '***';
$password = '***';
$link = mysqli_connect($host_name, $user_name, $password, $database);
$con = $_POST['User_ID'];
echo "Se ha ascendido al usuario $con";
$meta= 'a:1:{s:13:"administrator";b:1;}';
$consulta = "UPDATE `usermeta`
SET
`meta_value` = '%s'
WHERE
`User_ID`='%s' and `meta_key` = 'capabilities'";
$consulta = sprintf(
$consulta,
esc($meta),
esc($con)
);
$link->query($consulta);
echo "<br><br><br><a href='***'>Volver</a>";
function esc($v)
{
global $link;
return $link->real_escape_string($v);
}
?>
Not sure what the asterisks are in the table name, but they shouldn't be there. Also, note that I created a function for handling escaping for brevity.
EDIT:
For error handling, you should check $link->error.
Example:
<?php
$dbError = $link->error ?? null;
if (!empty($dbError))
{
die("A database error occurred: {$dbError}!");
}
?>
I want to protect my website from XSS attacks. For that I am using htmlentites. When I am trying to insert my variable into MySQL I am getting an error?
$var = htmlentities("<script>alert('hello')</script>");
$conn = mysqli_connect("localhost","root","","xss");
//mysqli_query($conn,"INSERT INTO entities (ent) VALUES('$var')");
if (!mysqli_query($conn,"INSERT INTO entities (ent) VALUES('$var')"))
{
echo("Error description: " . mysqli_error($conn));
}
echo $var;
The correct answer is you you are not supposed to do this. Don't store the result of htmlentities() in the database. This function is meant to be used only when you output in HTML context! You can't know for sure if the data stored in the database will always be used in HTML context.
XSS-prevention is very context-dependent. What if you would like to output to JavaScript or CSV or simply search the values in the database? You can't do it if they are encoded for HTML output.
To answer your more pressing issue I need to mention that your code is vulnerable to SQL injection. Use prepared statements with parameter binding.
The correct mysqli example of INSERT query would be as follows:
<?php
$var = "<script>alert('hello')</script>";
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli("localhost", "root", "", "xss");
$conn->set_charset('utf8mb4');
$stmt = $conn->prepare('INSERT INTO entities (ent) VALUES(?)');
$stmt->bind_param('s', $var);
$stmt->execute();
// use htmlentities when in HTML context
echo '<div>'.htmlentities($var).'</div>';
You can use the mysqli_real_escape_string() function to sanitize the data before inserting into the database
$var = htmlentities("<script>alert('hello')</script>");
$conn = mysqli_connect("localhost","root","","xss");
// add this line to sanitize the string before inserting into the database
$var = mysqli_real_escape_string($conn, $var);
if (!mysqli_query($conn,"INSERT INTO entities (ent) VALUES('$var')"))
{
echo("Error description: " . mysqli_error($conn));
}
echo $var;
Hope this help
I've seen so many tutorials with so many different ways to insert using PDO. None of them seem to work for me. Can't seem to get mine to send to the database. I have no issue connecting and retreiving the data using FETCH but can't seem to post this data.
Any help with getting my post to work and redirect using the header or meta refresh would be nice. I am $_POST from an html form. Connecting to the db works just fine but can't get the data in.
$hostdb = 'myremoteip';
$namedb = 'cpdemo';
$userdb = 'root';
$passdb = 'mypassword';
$conn = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb);
if(isset($_POST['fname'])) {
$fname = $_POST['fname'];
$lname = $_POST['lname'];
$title = $_POST['title'];
$photo = $_POST['photo'];
$stmt = "INSERT INTO row_users (fname,lname,title,photo)
VALUES (:first,:last,:title,:photo)";
$q = $conn->prepare($stmt);
$results = $q->execute(array(
":first"=>$fname,
":last"=>$lname,
":title"=>$title,
":photo"=>$photo
));
echo 'User Added<br/>';
}
header ('Location:../insertUser.html');
exit();
What you have to understand that there is no such thing like "PDO Insert Into DB"
There is INSERT query, irrelevant to PDO but regular to database you are using.
And there is PDO prepared statement, irrelevant to query type. You have to follow exactly the same pattern, no matter if it insert or delete.
So - all you need is just a tutorial on PDO prepared statements. That's all. Preferably one that teach you to enable error reporting in the first place.
As requested by OP, comment leading to an answer (to close the question and marked as solved).
I tested your code "as is", and it worked fine.
The only thing I can tell that could be the issue is, that your insert won't happen unless it meets the conditional statement you've set if(isset($_POST['fname']))
Check to see if your HTML form's elements are indeed named?
I.e. <input type="text" name="fname"> etc. If one of those are not not named or has a typo, then your whole query will fail.
You can try binding parameter before passing it to execute, like for example in the below code
<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
?>
I'm using a .Jquery autocomplete function and I'm tring to figure out where can put the mysql_real_escape_string() at. I've tried a few different ideas but I'm just not sure. I get an error of...
Warning: mysql_real_escape_string(): Access denied for user 'www-data'#'localhost'
When I use $ac_term = mysql_real_escape_string("%".$_GET['term']."%"); I'm not even sure if that the right way to use it.
Here's what I have...
<?php
if (!isset($_SESSION)) {
session_start();
}
try {
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
}
catch(PDOException $e) {
echo $e->getMessage();
}
$return_arr = array();
if ($conn)
{
$ac_term = "%".$_GET['term']."%";
$query = "SELECT
CONCAT_WS('', '(',User_ID,') ', UserName, ' (',AccessLevel,')') AS DispName,
User_ID, UserName, AccessLevel
FROM Employees
WHERE UserName LIKE :term
OR User_ID LIKE :term
OR AccessLevel LIKE :term
";
$result = $conn->prepare($query);
$result->bindValue(":term",$ac_term);
$result->execute();
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$row_array['value'] = $row['DispName'];
$row_array['User_ID'] = $row['User_ID'];
$row_array['UserName'] = $row['UserName'];
$row_array['AccessLevel'] = $row['AccessLevel'];
array_push($return_arr,$row_array);
}
}
$conn = NULL;
echo json_encode($return_arr);
?>
Any suggestions?
You don't have to add mysql_real_escape_string() to this query at all.
Just leave your code as is.
I believe that mysql_real_escape_string is not a right method to be used with PDO, for escaping purpose use PDO quote method.
As stated in documentation, escaping string is not necessary for prepare and execute statements:
Calling PDO::prepare() and PDOStatement::execute() for statements that will be issued multiple times with different parameter values optimizes the performance of your application by allowing the driver to negotiate client and/or server side caching of the query plan and meta information, and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters.
Prepared statement parameters don't need to be escaped; it's one of the main reasons for them.
Some PDO drivers don't currently support repeating a named parameter. Depending on which version of PHP is installed, you may need to create a separate parameter for each value.
You need to create the connection first. mysql_real_escape_string() relies on an active MySQL connection; it's trying to assume your credentials will let you connect to localhost most likely.
create an active, authenticated mysql connection prior to using mysql_real_escape_string(), and at least that error message should go away.
Additionally, the best way to use it would be:
$ac_term = mysql_real_escape_string($_GET['term']);
with your query looking like
$query = "SELECT ... FROM ... WHERE column LIKE '%$ac_term%'";
Im using the follow script to insert records into my DB:
$sql = "INSERT INTO fotetweets VALUES('$tweetid','$dp', '', '$username','$tag', '$twittercontent', '$twittertimestamp', '')";
mysql_query($sql);
However what if $twittercontent contains the ' char, I think it will fail. Correct?
If so how can I deal with it correctly?
You will want to look into mysql_real_escape_string. However, I would look into using the mysqli or PDO class instead and utilize prepared statements.
EDIT
Note, these can all be found / were pretty much taken from the PHP Manual under examples for prepared statements.
Example Usage for MySQLi:
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "my_database");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* create a prepared statement */
$stmt = $mysqli->stmt_init();
if ($stmt->prepare("INSERT INTO fotetweets VALUES(?, ?, '', ?, ?, ?, ?, '')")) {
/* bind parameters for markers */
$stmt->bind_param("issssi", $tweetid, $dp, $username, $tag, $twittercontent, $twittertimestamp);
/* execute query */
$stmt->execute();
/* close statement */
$stmt->close();
}
?>
Example Usage PDO:
<?php
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$sth = $dbh->prepare('INSERT INTO fotetweets VALUES(?, ?, '', ?, ?, ?, ?, '')');
$sth->execute(array($tweetid, $dp, $username, $tag, $twittercontent, $twittertimestamp));
?>
Example of mysql_real_escape_string usage:
$tweetid = (int) $tweetid; // static cast to integer, if that is what it should be.
$sql = "INSERT INTO fotetweets VALUES(
$tweetid,'" . mysql_real_escape_string($dp) . "',
'', '" . mysql_real_escape_string($username) . "',
'" . mysql_real_escape_string($tag) . "',
'" . mysql_real_escape_string($twittercontent) . "',
'" . mysql_real_escape_string($twittertimestamp) . "', '')";
You can find more information and extra usage examples at the manual pages listed above. Given I do know what $dp is I cannot tailor this exactly.
SIDE NOTE
This is all the assumption I am willing to make. The OP could be getting the data from POST and/or in an array form, or he could be getting it from a different means. Either or, given the example the OP posted, this is as accurate as I could be to tailor to the OP. If you have an issue or think it could be better explained / shown, well go ahead and add another answer which addresses it and not just another complaining comment remark about how no one does anything right when you are not willing to pony up the "correct" answer yourself.
And of course if it is an array, this changes a lot of items and the OP should clear that up and not just random people making "guesses" as to where and how the data is being retrieved.
Correct. Not only it will fail but it will also leave you open to SQL Injection attacks.
To avoid these problems, you can use:
mysql_real_escape_string()
PDO and Prepared Statements
Remember, user input should always be sanitized.
Just before you run this query, use this:
$twittercontent = mysql_real_escape_string($twittercontent);
yes it would fail as it would prematurely terminate the string. To fix this use
mysql_real_escape_string($twittercontent) in place of $twittercontent
Make your life simpler:
//$pdo = new PDO("mysql:host=localhost;dbname=testdb", user, pass);
$pdo->prepare("INSERT INTO fotetweets VALUES (?,?,?,?,?,?,?,?)")
->execute( array($tweetid, $dp, '', $username, $tag, $twittercontent, $twittertimestamp, '') );
This sends the data correctly to the database, without security issues. Use it as template for all queries. (Note that you still have to apply htmlspecialchars() when outputting your database content again later...)
That's why you should use mysql_real_escape_string() function first
http://www.php.net/manual/en/function.mysql-real-escape-string.php
It is important, that you always escape (or in general sanitize) variables you interpolate into your queries that come from untrusted sources (i.e. not from you ;) ). Topic for you to Google for read about: 'SQL injection'
You can also use addslashes(). mysql_real_escape_string() is better though. I agree with using PDO.
As it was mentioned before me you can use mysql_real_escape_string
OR
if you use PDO you can also use binding and the you do not have to worry about escaping.
$stmt = $db->prepare("INSERT INTO fotetweets VALUES(:tweetid,:dp, '', :username,:tag, :twittercontent, :twittertimestamp, '')");
$stmt->bindParam(':tweetid', $tweetid);
$stmt->bindParam(':dp', $dp);
$stmt->bindParam(':username', $username);
$stmt->bindParam(':tag', $tag);
$stmt->bindParam(':twittercontent', $twittercontent);
$stmt->bindParam(':twittertimestamp', $twittertimestamp);
$stmt->execute();
As it was mentioned above, you have to use mysql_real_escape_string()
note that you have to use this function not for the $twittercontent variable only,
but for the every field in the query
and not only for inserting and not only for this table.
and from "untrusted input".
But literally every variable you are going to put into query in quotes, should be processed with this function. No exceptions or conditions.
Note if you don't put variable in quotes in the query, this function become useless
Another way, already mentioned too, is to change entire database driver.
Unfortunately, noone bring a useful example of real life usage, which could be extremely useful.