Prepared statements in Extbase TYPO3 7.6 not working - php

I want to submit the query as a prepared statement, like below.
$query = $this->createQuery();
$query->getQuerySettings()->usePreparedStatement(TRUE);
$sqlParamList[] = 'test#gamil.com';
$sql = 'SELECT uid FROM table_name WHERE email = ?';
$query->statement($sql, $sqlParamList);
$result = $query->execute();
But I always get errors like below.
You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use near '?' at line 1'
Where I am wrong?

You need to parse your $sql to a prepared statement first:
$preparedSql = $this->objectManager->get(\TYPO3\CMS\Core\Database\PreparedStatement::class, $sql, 'table_name');
With $this->objectManager->get() you instantiiate the class PreparedStatement with the arguments $sql and 'table_name'.
This will change your $sql and parse the ? to be used as prepared statement.

Another approach:
$query = $this->createQuery();
$query->getQuerySettings()->usePreparedStatement(TRUE);
$sqlParamList = [
':email' => 'test#gamil.com'
];
$sql = 'SELECT uid FROM table_name WHERE email = :email';
$query->statement($sql, $sqlParamList);
$result = $query->execute();
Cannot test it, just an approach.

Related

How to escape sql injection from HANA placeholder

I have some HANA queries which use PLACEHOLDER input and of course I want to prevent an sql injection.
I try to use ? in odbc_prepare()
$query = <<<SQL
SELECT
col,
...
FROM table_name('PLACEHOLDER'=('$$some_key$$', ?))
WHERE col = ?
SQL;
$stmt = \odbc_prepare($conn, $query);
if ($stmt !== false) {
\odbc_execute($stmt, ['placeholder_value', 'where_value']);
}
but I receive this warning:
Warning: odbc_prepare(): SQL error: [SAP AG][LIBODBCHDB SO][HDBODBC] Syntax error or access violation;257 sql syntax error: incorrect syntax near "?": line 32 col 40 (at pos 1283), SQL state 37000 in SQLPrepare
and statement wasn't created. So my code now looks like this:
$query = <<<SQL
SELECT
col,
...
FROM table_name('PLACEHOLDER'=('$$some_key$$', 'placeholder_value'))
WHERE col = ?
SQL;
$stmt = \odbc_prepare($conn, $query);
if ($stmt !== false) {
\odbc_execute($stmt, ['where_value']);
}
As I see here htmlspecialchars() is not enough to prevent an SQL injection.
I can't remove input placeholder, I don't own HANA.
Is there any other way to prevent SQL injection in PLACEHOLDER?
The (old) placeholder syntax ('PLACEHOLDER'=('<varname>', '<var value>')) you're using here does not allow for bind variables.
Instead, the new placeholder syntax (PLACEHOLDER."<varname>"=>?) allows using bind variables.
In your code this would look like this:
$query = <<<SQL
SELECT
col,
...
FROM table_name (PLACEHOLDER."$$some_key$$" => ?)
WHERE col = ?
SQL;
$stmt = \odbc_prepare($conn, $query);

php pdo sql query Error : 1064 with LIKE

My PDO query is throwing an error
42000 1064 You have an error in your SQL syntax
$sql = "SELECT * FROM {$this->config->__get('table_medicine')} WHERE patient_id = ? AND medicine LIKE %?%";
$query = $this->dbh->prepare($sql);
$data = array($patient_id, $medicine);
$response = $query->execute($data) or die(implode(" ", $query->errorInfo()));
Can someone see what am I doing wrong?
The % need to be inside the string argument to LIKE. Either use CONCAT() in the SQL:
$sql = "SELECT * FROM {$this->config->__get('table_medicine')}
WHERE patient_id = ? AND medicine LIKE CONCAT('%', ?, '%')";
or do the concatenation in PHP:
$data = array($patient_id, '%'.$medicine.'%');

PDO Update Statement not working

I am trying to update a simple query and I keep getting the following 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 ':cat_name, menu_category_description = :cat_desc WHERE id = :id' at line 1
The query I am using looks perfectly valid. I don't know why it keeps showing that error message.
Below is my query I am using.
$query = "UPDATE menu_categories SET menu_category_name = :cat_name, menu_category_description = :cat_desc WHERE id = :id ";
$stmt = $db->query($query);
$stmt->execute([":cat_name" =>$category_name, ":cat_desc" => $category_description, ":id" => $id ]);
You need to first prepare your query: (you're querying instead of preparing)
change this line:
$stmt = $db->query($query);
to:
$stmt = $db->prepare($query);
then change this line
$stmt->execute([":cat_name" =>$category_name, ":cat_desc" => $category_description, ":id" => $id ]);
to (and remove the square brackets)
$stmt->execute(":cat_name" =>$category_name, ":cat_desc" => $category_description, ":id" => $id);
See if this works for you,
$query = "UPDATE menu_categories SET menu_category_name = :cat_name, menu_category_description = :cat_desc WHERE id = :id ";
$stmt = $db->prepare($query);
$stmt->bindParam(':cat_name', $category_name);
$stmt->bindParam(':cat_desc ', $category_description);
$stmt->bindParam(':id', $id);
$stmt->execute();
Also, where are you defining values for your $category_name, $category_description, $id? Make sure they are not empty.
Here's an example of Updating PDO
$pdo = Database::getInstance();
$stmt = $pdo->db->prepare("UPDATE people SET reset='1', active=:acTive WHERE user_id=:id limit 1");
$stmt->bindParam(':acTive', $_POST['active_key']);
$stmt->bindParam(':id', $_POST['id']);
$stmt->execute();
Hope it helps

Unable to concatenate sql in pdo statement [duplicate]

This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 2 years ago.
I currently have a Get varible
$name = $_GET['user'];
and I am trying to add it to my sql statement like so:
$sql = "SELECT * FROM uc_users WHERE user_name = ". $name;
and run
$result = $pdo -> query($sql);
I get an invalid column name. But that doesn't make sense because if I manually put the request like so
$sql = "SELECT * FROM uc_users WHERE user_name = 'jeff'";
I get the column data, just not when I enter it as a get variable. What am I doing wrong. I am relatively new to pdo.
Update:
Now I have the following:
$name = $_GET['user'];
and
$sql = "SELECT * FROM uc_users WHERE user_name = :name";
//run the query and save the data to the $bio variable
$result = $pdo -> query($sql);
$result->bindParam( ":name", $name, PDO::PARAM_STR );
$result->execute();
but I am getting
> 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 ':name' at line
> 1
For your query with the variable to work like the one without the variable, you need to put quotes around the variable, so change your query to this:
$sql = "SELECT * FROM uc_users WHERE user_name = '$name'";
However, this is vulnerable to SQL injection, so what you really want is to use a placeholder, like this:
$sql = "SELECT * FROM uc_users WHERE user_name = :name";
And then prepare it as you have:
$result = $pdo->prepare( $sql );
Next, bind the parameter:
$result->bindParam( ":name", $name, PDO::PARAM_STR );
And lastly, execute it:
$result->execute();
I find this best for my taste while preventing SQL injection:
Edit: As pointed out by #YourCommonSense you should use a safe connection as per these guidelines
// $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$sql = 'SELECT * FROM uc_users WHERE user_name = ?';
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
// perhaps you'll need these as well
$count = $result->num_rows;
$row = $result->fetch_assoc();
/* you can also use it for multiple rows results like this
while ($row = $result->fetch_assoc()) {
// code here...
} */
BTW, if you had more parameters e.g.
$sql = 'SELECT * FROM table WHERE id_user = ? AND date = ? AND location = ?'
where first ? is integer and second ? and third ? are string/date/... you would bind them with
$stmt->bind_param('iss', $id_user, $date, $location);
/*
* i - corresponding variable has type integer
* d - corresponding variable has type double
* s - corresponding variable has type string
* b - corresponding variable is a blob and will be sent in packets
*/
Source: php.net
EDIT:
Beware! You cannot concatenate $variables inside bind_param
Instead you concatenate before:
$full_name = $family_name . ' ' . $given_name;
$stmt->bind_param('s', $full_name);
Try this .You didn't put sigle quote against variable.
$sql = "SELECT * FROM uc_users WHERE user_name = '". $name."'";
Note: Try to use Binding method.This is not valid way of fetching data.
$sql = "SELECT * FROM 'uc_users' WHERE user_name = '". $name."' ";

Insert a PHP variable in a MySql SQL Statement

I'm trying to do like this using PHP and MySql PDO:
//PHP Variables
$msg_a = 'Too Little';
$msg_b = 'Score OK';
$sql = "select if(stdScore >= stdRequired, $msg_a, $msg_b) from scores;"
$results = $conn->prepare($Sql);
$results->execute();
AFAIK this should have worked. But I keep getting the following error message:
Fatal error: Uncaught exception 'PDOException' with 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 '
How can something like this be done?
$results = $conn->prepare($Sql);
---------------------------------------------^ (capital S)
it should be with a lowercase s
$results = $conn->prepare($sql);
because you have:
$sql = "select if(stdScore >= stdRequired, $msg_a, $msg_b)
from scores";(//semicolon after double quotes)
---^
with a lowercase s ($sql)
Can you try this,
$sql = "select if(stdScore >= stdRequired, $msg_a, $msg_b) from scores";
$results = $conn->prepare($sql);
Have you tried it this way ?
$sql = "select if(stdScore >= stdRequired, "'.$msg_a.'", "'.$msg_b.'") from scores;"
Since you're already using PDO don't do query string interpolation leaving your code vulnerable to sql injections and value escaping problems. Instead use prepared statements properly.
Your code could've looked something like
$msg_a = 'Too Little';
$msg_b = 'Score OK';
// use placeholders in a query string
$sql = "SELECT IF(stdScore >= stdRequired, :msg_a, :msg_b) msg FROM scores";
// prepare the statement
$query = $conn->prepare($sql);
// bind parameters and execute the query
$query->execute(array(':msg_a' => $msg_a, ':msg_b' => $msg_b));
// fetch the resultset
$rows = $query->fetchall(PDO::FETCH_ASSOC);

Categories