I am using the following code to strip out unwanted characters but it is not stripping out everything and throwing a MySQL error:
$commentmessage = strip_tags($commentmessage);
$commentmessage = htmlentities($commentmessage, ENT_QUOTES);
What code would I use to strip out anything that might cause a MySQL error?
The message I am receiving is:
Error message: SQLSTATE[42000]: Syntax error or access violation: 1064 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 'omg thats the one". One of the logo's we really liked was 1049859 where the f' at line 2**
Evidently you're building your query like so:
$query = "INSERT INTO foo VALUES ('$bar')";
which is breaking because the text of $bar contains single quotes. '
No. *hits you with a rolled-up newspaper* Bad developer.
I could just throw you a string escaping function, or I could show you to do it right like:
$bar = "I am a problematic string!'; DROP TABLE USERS -- "
$query = "INSERT INTO foo VALUES (?)";
$stmt = $dbh->prepare($query);
$stmt->execute(array($bar));
Or:
$bar = "I am a problematic string!'; DROP TABLE USERS -- "
$query = "INSERT INTO foo VALUES (:bar)";
$stmt = $dbh->prepare($query);
$stmt->execute(array('bar'=>$bar));
When you prepare a query like this PHP/PDO/MySQL get together and pre-agree on what types your placeholders are. So your strings are treated like strings without the need for escaping characters. This both prevents rogue single quotes from breaking your query, and help protect you from SQL injection attacks.
You can also re-use prepared statements to increase performance: [relative to un-prepared statements since the SQL only needs to be parsed once, rather than once per query]
$query = "INSERT INTO foo VALUES (?)";
$stmt = $dbh->prepare($query);
foreach( $bars as $bar ) {
$stmt->execute(array($bar));
}
Related
OK, so I have gone round and round with this now for 2 hours and cannot figure out where the so-called SQL syntax error is. I finally re-wrote the prepared statement as a standard query - and it works fine, literally identical syntax.
Prepared Statement Code: (NOT working)
if ($account_info = $mysqli->prepare("SELECT users.specid, users.username ?
FROM users ? WHERE users.id = ?")) {
//A SWITCH to determine bind_param and bind_result
} else {
//Error output
}
The above results in the following MYSQL error:
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 '? FROM users ? WHERE users.id = ?' at line 1
Now if I literally change the '?' to $variables and make the prepared statement into a normal query like:
if ($account_info = $mysqli->query("SELECT users.specid, users.username $param1
FROM users $param2 WHERE users.id = $param3")) {
//Fetch array and set variables to results
} else {
//Error output
}
The above code WORKS as expected with no errors.
For those curious what the $variables are in the specific switch case I'm testing:
$param1 = ', tenants.paper';
$param2 = ', tenants';
$param3 = $_SESSION['user_id'].' AND tenants.id = users.specid';
So why does one work but not the other when they have the same syntax??? It doesn't even get to the bind_param part!? I'd prefer to use the prepared statement method.
You can't pass object nane (tablename or columnname ) as param .
So users.username ? and users ? as you are trying to use are wrong ..
passing param is not a string substituition ..
This kind of action are disallowed by param binding
and you should avoid this ..but if you really need then try with string concatenation
You only bind values for parameter bindings. Not parts of SQL. ::bind_param
What you are trying to do with $param1 = ', tenants.paper'; is already SQL injection. Prepared statements are build to prevent this.
You should make a method per query instead of a generic query.
You cannot bind complex query parts and columns in a query. I also don't understand why you need to parametrise strings you explicitly set in your code.
Do this instead:
$param = $_SESSION['user_id'];
if ($account_info = $mysqli->prepare("SELECT users.specid, users.username, tenants.paper
FROM users JOIN tenants ON tenants.id=users.specid WHERE users.id = ?")) {
//A SWITCH to determine bind_param and bind_result
} else {
//Error output
}
If you (at any point in the future) need to escape column names from user input (though you shouldn't allow users such power to begin with) do this:
$columnNameFromUserInput = $_GET["column"];
$columnNameFromUserInput = "`".str_replace("`","",$columnNameFromUserInput)."`";
This should be enough.
Do not put query segments that have parts that need escaping in a variable. Put the parts that need escaping in their own separate variables so you can bind them is the whole idea here.
Example:
$param1 = ', tenants.paper'; //Bad has a comma in it, should be `tenants`.`paper` and the comma should go in the query itself
$param2 = ', tenants'; //Bad, though you have to use JOIN in any SQL language after 1992
//The next part is very very bad.
// You have something that needs escaping mixed with things that compose a query. Split them.
$param3 = $_SESSION['user_id'].' AND tenants.id = users.specid';
php/mysql
I keep getting this error: "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 '1' at line 1".
I'm trying hard to make this query to happen. It works, it inserts into the mysql database but this error appears every time. I've tried to use everything in the same line, changed double quotes to single quotes, removed all the whitespaces inserting everything in the samen line, changing the way I pass the variables({$variable} to '.$variable.') and everything else. I've seen a couple of stackoverflow questions related to this but with different solutions.
I know that we can't pass '' in a numeric fields.
I think I'm out of options now. Need help!
This error keeps showing but the data is correctly inserted in my table
here is the code:
$user_id = get_current_user_id();
$prescription_name = $_POST['prescription_name'];
$date_created = date('Y-m-d');
$last_updated = date('Y-m-d');
$right_eye_sphere = $_POST['right_eye_sphere'];
$left_eye_sphere = $_POST['left_eye_sphere'];
$right_eye_cylinder = $_POST['right_eye_cylinder'];
$left_eye_cylinder = $_POST['left_eye_cylinder'];
$right_eye_axis = $_POST['right_eye_axis'];
$left_eye_axis = $_POST['left_eye_axis'];
$pd = $_POST['pd'];
$date_of_birth = $_POST['date_of_birth'];
$file_path = $_POST['file_path'];
$add_query = "INSERT INTO wew_prescription (
prescription_id,
user_id,
prescription_name,
date_created,
last_updated,
right_eye_sphere,
left_eye_sphere,
right_eye_cylinder,
left_eye_cylinder,
right_eye_axis,
left_eye_axis,
pd,
date_of_birth,
file_path
) Values (
NULL,
{$user_id},
'{$prescription_name}',
'{$date_created}',
'{$last_updated}',
'{$right_eye_sphere}',
'{$left_eye_sphere}',
'{$right_eye_cylinder}',
'{$left_eye_cylinder}',
'{$right_eye_axis}',
'{$left_eye_axis}',
'{$pd}',
'{$date_of_birth}',
'{$file_path}'
)";
$sql = $dbCon->query($add_query);
if (!mysqli_query($dbCon,$sql)){
die('Error: ' . mysqli_error($dbCon));
}else{
mysqli_query($dbCon,$sql);
echo "dados atualizados!";
}
The error is coming from this line:
if (!mysqli_query($dbCon,$sql)){
$sql contains the result of
$dbCon->query($add_query);
Since that query was successful, $sql contains TRUE. mysqli_query() requires the second argument to be a string, so TRUE becomes "1", so you're effectively doing:
if (!mysqli_query($dbCon, "1")) {
That's not a valid query, so you get an error.
I think what you really meant to do was:
if (!$sql) {
die('Error: ' . $dbCon->error);
} else {
echo "dados atualizados!";
}
You don't need to keep calling mysqli_query() repeatedly.
You should also learn to code using prepared statements instead of substituting variables into the query, to prevent SQL injection.
Given this SQL
UPDATE `mytable`
SET `mycolumn`='karla bailey-pearapppppppp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
WHERE `id`=5619
Why will mysqli_real_escape_string() not escape this string properly?
Trying to use this SQL query after escaping the column's value produces this mysqli error:
"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 ''karla bailey-pearapppppppp\\\\\\\\\\\\\\\\\\\\\\\\\\\' at line 3"
Is there a limit to the number of backslashes that can be escaped?
Are you escaping the ENTIRE string? e.g.
$sql = "UPDATE .... \\\\\\\'";
$escaped = mysqli_real_escape_string($link, $sql);
If so, that's incorrect. You are trashing the string by doing that. You'll also be escaping the ' that delimit your where clause value. Escaping should be performed only VALUES that you're inserting into the string. e.g.
$name = "Miles O'Brien"; // ' in name would cause syntax error
$bad_sql = "SELECT '$name'";
$broken_sql = mysqli_real_escape_string($link, $bad_sql);
// produces: SELECT \'Miles O\'Brien\'
$ok_sql = "SELECT '" . mysqli_real_escape_string($link, $name) . "'";
// produces: SELECT 'Miles O\'Brien';
Ok, so I found the problem. The application checks for the value length > column maximum, and if the value is too great, truncates the value AFTER the escape is done - thereby breaking the escaped value (very isolated case where this would occur, this code has been in place for years).
Ergo, can't truncate a value that ends in backslashes after the value is already escaped.
I'm trying to remove apostrophes within certain fields of a SQL Server query within PHP, and despite the fact that I'm throwing in the extra set of ''s in the string pattern section, it still errors out when an apostrophe is found within the result.. I'm not sure what I'm doing wrong here, any help would be hugely appreciated!
This section of the code loops through each row result from a web scrape and throws it into a new table row for each result. The functionality works, but it errors out and breaks the loop whenever an apostrophe is returned by the query.
for($i = 1, $max = count($table); $i < $max; ++$i) {
$dbrow = $table[$i];
$insquery = "INSERT INTO db.schema.table (EVENT_ID, EVENT_CODE, DESCRIPTION,
STATUS, SITE_STATUS, CITY, COUNTY, ZIP, STATE, STARTDATE, ENDDATE, YEARS_PRIOR, TOTAL_PRICE,
CUSTODIAN_FEE, ESTIMATED_FEES, FEE_TYPE, SD, PROGRAM, RC_LN, BUF_AMOUNT, LOC_PREM,
ST_PREM, SNAPSHOT_DATE) VALUES('".$dbrow[0]."','".$dbrow[1]."', replace('".$dbrow[2]."','''', ''),'".$dbrow[3]."','".$dbrow[4]."', replace('".$dbrow[5]."','''', ''), replace('".$dbrow[6]."','''', ''),'".$dbrow[7]."','".$dbrow[8]."','".$dbrow[9]."','".$dbrow[10]."','".$dbrow[11]."','".$dbrow[12]."','".$dbrow[13]."','".$dbrow[14]."','".$dbrow[15]."', replace('".$dbrow[16]."','''', ''), replace('".$dbrow[17]."','''', ''), replace('".$dbrow[18]."','''', ''), replace('".$dbrow[19]."','''', ''),'".$dbrow[20]."','".$dbrow[21]."','".$dbrow[22]."');";
sqlsrv_query($conn, $insquery) or die ("Error in query: $insquery. ".sqlsrv_errors());
echo $insquery . "<br>";
};
Of course it does. You're trying to replace the apostrophes in SQL itself. Consider this statement:
replace('don't','''', '')
How is SQL Server supposed to evaluate that? It opens a string, then after three letters closes that string, then encounters an errant t character resulting in a syntax error.
The query itself needs to be syntactically valid for SQL to execute it. SQL can't fix syntax errors in its own code. You would need to conduct the replacement for single-quotes in PHP, not in SQL.
In any event, there's a really neat solution to all of this. Prepared statements. Don't worry about quoting at all, let the engine handle that for you. For example:
$sql = "INSERT INTO Table_1 (id, data) VALUES (?, ?)";
$params = array(1, "some data");
$stmt = sqlsrv_query($conn, $sql, $params);
This, of course, has the added benefit of helping to protect you from SQL injection attacks, something to which your current code is very likely vulnerable.
I'm trying how best to prepare my SQLite SQL strings in PHP. The SQLite3 class comes with an escapeString() function, but here are my issues:
Try 1)
$sql = "INSERT INTO items ('id','content','title','created') VALUES ('4e7ce7c18aac8', 'Does this work', NULL, '2011-09-23T16:10:41-04:00');";
$sql = SQLite3::escapeString( $sql );
echo ($sql);
This results in a string that's all jacked up:
INSERT INTO items (''id'',''content'',''title'',''created'') VALUES
(''4e7ce7c18aac8'', ''Does this work'', NULL,
''2011-09-23T16:10:41-04:00'');
Those aren't double quotes, rather doubled-up single quotes. Obviously won't work.
Try 2)
$sql = 'INSERT INTO items ("id","content","title","created") VALUES ("4e7ce7c18aac8", "Does this work", NULL, "2011-09-23T16:10:41-04:00");';
$sql = SQLite3::escapeString( $sql );
echo ($sql);
This results in:
INSERT INTO items ("id","content","title","created") VALUES
("4e7ce7c18aac8", "Does this work", NULL,
"2011-09-23T16:10:41-04:00");
This query works fine, but the escapeString function hasn't modified anything as there's nothing to escape...
Try 3)
$sql = 'INSERT INTO items ("id","content","title","created") VALUES ("4e7ce7c18aac8", "Doesn't this work", NULL, "2011-09-23T16:10:41-04:00");'; $sql = SQLite3::escapeString( $sql ); echo ($sql);
Here's the big problem- Now I have an apostrophe in one of my values. It won't even make it to escapeString() because PHP will throw an error on the invalid string:
PHP Parse error: syntax error, unexpected T_VARIABLE, expecting ','
or ';'
How am I supposed to be approaching this? Keep in mind that in the actual code my parameter values will be variables, so am I supposed to escape each variable before I pass it into the string? If so, what function do I use?
Finally, what's the point of escapeString()?? I can't figure out how it's supposed to be used correctly.
You don't escape the entire query. You escape unsafe data you're inserting into the query, e.g.
$unsafe = $_GET['nastyvar'];
$safe = SQLite3::escapeString($unsafe);
$sql = "INSERT INTO table (field) VALUES ($safe);";
echo ($sql);