Strange behavior of mysql query string in PHP - php

I'm toying around with mysql and PHP and hit a VERY strange problem:
After establishing a successful database connection I set two variables for the query:
$searchcolor = $_SESSION["color"];
$searchprice = $_POST["price"];
$query = "SELECT `toys`.`id` FROM `database`.`toys` WHERE `toys`.`color` = $searchcolor AND `toys`.`price` = $searchprice;";
$result = mysqli_query($link, $query);
echo $query;
This querys won't work. When echoing it, it reads the correct string, like:
SELECT `toys`.`id` FROM `database`.`toys` WHERE `toys`.`color` = brown AND `toys`.`price` = 1500;
This code, however, works just fine:
$searchcolor = $_SESSION["color"];
$searchprice = $_POST["price"];
$query = "SELECT `toys`.`id` FROM `database`.`toys` WHERE `toys`.`color` = $searchcolor AND `toys`.`price` = 1500;";
$result = mysqli_query($link, $query);
echo $query;
First I though the $searchprice wasn't getting it's content by the $_POST array correctly. But the echoed search query in the first example seems to be fine.
It also works when setting $searchprice = 1500; instead of getting the $_POST-value.
I tried casting it to integer and stuff, but that didn't worked.
Cheers and thanks for every hint on this!
(The code is shortened!)
Table structure of toys:
id int(10)
name varchar(10)
color varchar(10)
price int(20)
Edit:
Woah, just made an interesting discovery:
echo "-".$searchprice."-";
Gives -5-
if ($searchprice == 5){echo "1";}
if ($searchprice == "5"){echo "2";}
Gives.. nothing?!
var_dump($searchprice);
Gives string(14) "5"
Edit:
echo bin2hex($searchprice);
Gives 3c6e6f62723e353c2f6e6f62723e (?!)
Solution: I used a unicode character in the submitting form. That broke everything. Lesson: Avoid unicode.

First of all you should read this: How can I prevent SQL injection in PHP?
Try this:
$q = mysqli_prepare($link, 'SELECT toys.id FROM toys WHERE toys.color = ? AND toys.price = ?');
mysqli_stmt_bind_param($q, 'si', $searchcolor, $searchprice); //d for double
$searchcolor = $_SESSION['color'];
$searchprice = $_POST['price'];
mysqli_stmt_execute($q);
Before that you should connect properly with DB. I see that you used database in FROM.
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');

Related

PHP code does not recognize some values

EDIT: Thank you all for the very quick answers! I have been at this for a while, trying to figure out why $id was being recognized and why the strings weren't. I feel a bit silly now seeing the obvious answer but I'm relieved to have it working.
I apologize if this has been answered before, I've looked for hours and could not find something similar to help me figure this out.
I am trying to update a row in my database of devices with new information. Problem is, the php file only recognizes $data->devID; and nothing else.
If I have something like
$sql = "UPDATE devices SET devName = 'static test string', description = 'static test string' WHERE devID = $id";
the entry with the correct ID will update in my database table just fine.
If I try
$sql = "UPDATE devices SET devName = $name, description = $desc WHERE devID = $id";
it does not work.
Where am I going wrong?
HTML:
<div data-ng-repeat="info in deviceInfo">
<form class="deviceInfo">
<h2>Device ID: {{info.devID}}</h2>
<p>Device Name:</p>
<input type="text" data-ng-model="info.devName">
<p>Device Description:</p>
<textarea data-ng-model="info.description"></textarea>
<p>Device Available: {{info.isAvailable}}</p>
<input type="submit" name="Update" value="Update" data-ng-click="updateInfo(info.devID, info.devName, info.description)">
</form>
</div>
updateDeviceInfo.php:
<?php
$data = json_decode(file_get_contents("php://input"));
include('config.php');
$id = $data->devID;
$name = $data->devName;
$desc = $data->description;
$sql = "UPDATE devices SET devName = $name, description = $desc WHERE devID = $id";
$qry = $conn->query($sql);
$data = $qry;
$sql = "SELECT * FROM devices";
$qry = $conn->query($sql);
$data = array();
if($qry->num_rows > 0){
while($row = $qry->fetch_object()){
$data[] = $row;
}
}else {
$data[] = null;
}
$conn->close();
echo json_encode($data);
controller.js:
$scope.updateInfo = function($paramID, $paramName, $paramDesc){
console.log($paramID);
console.log($paramName);
console.log($paramDesc);
$scope.dataOneTest = {
devID: $paramID,
devName: $paramName,
description: $paramDesc
};
console.log($scope.dataOneTest.devID);
$http.post('./js/updateDeviceInfo.php', {'devID': $paramID, 'devName': $paramName, 'description': $paramDesc})
.success(function(data){
$scope.results = data;
})
.error(function(err){
$log.error(err);
})
}
tl;dr You are almost certainly performing SQL injection on yourself both by inserting variables directly into a query and by failing to use proper quotation marks around them.
You need to use prepared statements, rather than concatenating variables directly into your query. If, for example, $data->devName contained something nefarious like NULL --, that would toast your entire table. And that's a very mild example of how badly things could go. Prepared statements would render that example (and pretty much all other examples) harmless.
Short-Term Fix
As a short-term fix, put quotation marks in the query and escape your data, like this:
$id = your_database_escape_function($data->devID);
$name = your_database_escape_function($data->devName);
$desc = your_database_escape_function($data->description);
$sql = "UPDATE devices SET devName = '$name', description = '$desc' WHERE devID = $id";
substituting your database's corresponding escaping function for your_database_escape_function(). For example, use $conn->real_escape_string() if $conn is a MySQLi object. See the manual.
The Real Fix
Here's how you really do it correctly, and the solution you should implement ASAP. That is, do this before you go any further if at all possible. Use prepared statements.
Read this entire Q&A and this cheat sheet from OWASP (no affiliation) for more information.
change this becuase description and devName which are string should be quoted
$sql = "UPDATE devices SET devName = $name, description = $desc WHERE devID = $id";
to
$sql = "UPDATE devices SET devName = '".$name."', description = '".$desc."' WHERE devID = $id";
Try this, $sql = "UPDATE devices SET devName = '$name', description = '$desc' WHERE devID = $id";
As title and description are string it requires single quote wrapping inside double quotes.

Retrieving data from database gives error

Can anyone help me with this? My code won't run and I can't figure out why not.
<?php
include('connect-db.php');
if (isset($_GET['naam']))
{
// query db
$naam = $_GET['naam'];
$result = mysql_query("SELECT * FROM planten WHERE naam=$naam")
or die(mysql_error());
$row = mysql_fetch_array($result);
if($row)
{
// get data from db
$cat = $row['cat'];
$mintemp = $row['mintemp'];
$uitleg = $row['uitleg'];
$img = $row['img'];
}
}
?>
The connection is working and active, and the database name & row names are correct.
Try this
$result = mysql_query("SELECT * FROM planten WHERE naam='".$naam."'") or die(mysql_error());
I think the problem is in your query statement. Since $naam is string you need to use quotes to enclose the string in query. Please chnage your query statement as below and try:
$result = mysql_query("SELECT * FROM `planten` WHERE `naam` ='$naam'");
I guess your $naam is supposed to be a string. You should escape and quote it. Otherwise it'll be interpreted by SQL as a bogus column name.
if (isset($_GET['naam']))
{
// query db
$naam = mysql_real_escape_string($_GET['naam']);
$result = mysql_query("SELECT * FROM planten WHERE naam='$naam'")
or die(mysql_error());
...
This would be safer and easier if you use PDO with SQL query parameters. No need to escape anything or worry about quotes, because it's all taken care of for you by using a parameter.
if (isset($_GET['naam']))
{
// query db
$sql = "SELECT * FROM planten WHERE naam=?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$_GET['naam']]);
...
FYI the old "mysql_connect()" API was deprecated in PHP 5.5 (June 2013), and has been removed in PHP 7.0 (Dec 2015). See http://php.net/manual/en/mysqlinfo.api.choosing.php.
I recommend using PDO.

How to escape apostrophe in php variable for select query

I have tried escaping the query string and the $variable containing the apostrophe using the mysqli_real_escape_string the variable value is coming form the database. I am getting the following 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 '\'Shamrock Rovers%\' AND away_team like \'St Patrick's Athletic%\'' at line 1
The apostrophe is not getting escaped by the quotes around the comparison values is.
Here is the query as it appears in the PHP file:
$homeTeam = filter_input(INPUT_GET, 'homeTeam', FILTER_SANITIZE_STRING);
$homePlayers = "select * from players where team_name like $homeTeam";
$homePlayers = mysqli_real_escape_string($dbc, $homePlayers);
$homePlayersResult = mysqli_query($dbc, $homePlayers);
And echoed out to the browser:
select * from players where team_name like Shamrock Rovers
I have tried it a number of different ways with no variation in results i feel i am overlooking something simple.
Thanks in advance.
Edit 1
Updated Code
$homeTeam = filter_input(INPUT_GET, 'homeTeam', FILTER_SANITIZE_STRING);
$homeTeam = mysqli_real_escape_string($dbc, $homeTeam);
echo "<br>".$homeTeam."<br>";
$homePlayers = "select * from players where team_name like '$homeTeam%'";
$homePlayersResult = mysqli_query($dbc, $homePlayers);
This Script recieves 3 parameters from a processing script
header("location: ../scorer.php?gameWeek=$gameWeek&homeTeam=$homeTeam&awayTeam=$awayTeam");
outputs
select * from players where team_name like 'St Patrick's Athletic%'
Edit 2
after entering the query in to mysql command window nothing happens when i submit the query once but when i enter it again i get the following err.
like $homeTeam";
you need to quote that variable.
like '$homeTeam'";
or
like '$homeTeam%'";
since this is a string, as per your like Shamrock Rovers
However I don't know why you're using
$homePlayers = mysqli_real_escape_string($dbc, $homePlayers);
^^^^^^^^^^^^
while escaping your query: (?)
$homePlayers = "select * from players where team_name like $homeTeam";
^^^^^^^^^^^^
You probably meant to use:
$homePlayers = mysqli_real_escape_string($dbc, $homeTeam);
Consider using parametrized queries such as mysqli with prepared statements, or PDO with prepared statements instead.
Edit: (test)
This is what I used to successfully query a test table of mine, being "users".
<?php
$DB_HOST = 'xxx';
$DB_USER = 'xxx';
$DB_PASS = 'xxx';
$DB_NAME = 'xxx';
$Link = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
if($Link->connect_errno > 0) {
die('Connection failed [' . $Link->connect_error . ']');
}
$_GET['homeTeam'] = "St Patrick's Athletic";
$username = $_GET['homeTeam'];
$homeTeam = filter_input(INPUT_GET, 'homeTeam', FILTER_SANITIZE_STRING);
$homePlayers = mysqli_real_escape_string($Link, $homeTeam);
$homePlayers = "select * from users where username like '$homeTeam%'";
$homePlayersResult = mysqli_query($Link, $homePlayers);
echo "Names found like: " . $username;
echo "<br>";
while($row = mysqli_fetch_array($homePlayersResult)){
echo $row['username'];
echo "<br>";
echo "".$row['my_row']."";
echo "<br>";
}
Plus, make sure that your column is indeed VARCHAR and its length long enough and that your input is a "text type".
Sidenote:
You don't need this which will break your query:
$homeTeam = filter_input(INPUT_GET, 'homeTeam', FILTER_SANITIZE_STRING);
since you're already using mysqli_real_escape_string() to sanitize your input.
Something that we've discussed during our chat which was resolved, yet I did already mention the above before chatting which was the solution after all.

Mysql Fetch not working

i really dont know why this code isnt working.. database connection works, the timestamp is written to the database.
But i cant figure out why i get a blank page with this code here (i should see the timestamp as echo).
Anyone an idea about this ?
Thank you!
<?php
$user = "daycounter";
$password = "1234";
$database = "daycounter";
$host = "localhost";
$date = time();
// Create connection
$conn = new mysqli($host, $user, $password, $database);
// Check connection
if ($conn->connect_error) {
die("Error: " . $conn->connect_error);
}
//Insert timestamp in database
$sql = "INSERT INTO datum (datum)
VALUES ('".$date."')";
//check if that worked
if ($conn->query($sql) === TRUE) {
echo "That worked!";
}
//get timestamp from db and display it as echo
$select = "SELECT 'datum' FROM 'daycounter'";
$result = mysql_query($select);
while($row = mysql_fetch_object($result))
{
echo "$row->datum";
}
?>
You're using a mysqli DB connection, but calling mysql to do your select. You cannot mix/match the database libraries like that. If you'd had even minimal error checking, you'd have been told that there's no connection to the db:
$result = mysql_query($select) or die(mysql_error());
^^^^^^^^^^^^^^^^^^^^^
Plus, your select query has syntax errors. 'daycounter' is a string literal - you cannot select FROM a string. 'datum' would be syntactically correct, you can select a string literal from a table, but most like you want:
SELECT datum FROM daycounter
or
SELECT `datum` FROM `daycounter`
Neither of those words are a reserved word, so there's NO need to quote them, but if you're one of those people who insist on quoting ALL identifiers, then they must be quoted with backticks, not single-quotes.
$select = "SELECT 'datum' FROM 'daycounter'";
$result = mysqli_query($conn, $select);
while($row = mysqli_fetch_object($result)) {
echo "$row->datum";
}

Mysql fetch user data returning nil value

I recently received -3 ratings for my recent question though the solution wasn't provided. My apologies if I posted something which I shouldn't have.
Alright so it is related to that ques only I have this code:
$data = mysql_connect("localhost", "user", "pass");
mysql_select_db("dbname");
$data = mysql_query("SELECT `location` FROM `upload` WHERE `name` = '".$result['name']."'")
or die(mysql_error());
$info = mysql_fetch_array( $data );
$display_url = $info['createlink'];
So when I echo $display_url it returns nil value and in db I checked the createlink field and the value stored there is a link.
And when I use
$display_url = $info['location'];
It returns perfect value.
~~The field at createlink contains 'http://www.exdomain.com/create/create.php?t=BATMAN_SLAPPING_ROBBIN.jpg'
~~The field at location contains 'http://www.exdomain.com/create/img/BATMAN_SLAPPING_ROBBIN.jpg'
You're not requesting the createlink field from the table, only location. Change your query to this:
$data = mysql_query("SELECT `location`,`createlink` FROM `upload` WHERE `name` = '".$result['name']."'")
You should also move away from the deprecated mysql_* functions and switch to PDO/mysqli so that your code will work in future versions of php. This will also allow you to parametrize your queries to prevent SQL injection.

Categories