MYSQLi Creates Database with ? as name - php

I wrote an Install File for my own CMS which I'm working atm. I changed the SQL statements to make it a bit saver but now nothing works and I can't figure out why...
I change my code from:
$db = new mysqli($_POST['db_ip'], $_POST['db_user'], $_POST['db_key'], '', $_POST['db_port']);
if(!$db) {
exit('Connection error to database');
}
$query = "CREATE DATABASE IF NOT EXISTS $db_name;";
$ergebnis = mysqli_query($db, $abfrage);
to:
$db = new mysqli($_POST['db_ip'], $_POST['db_user'], $_POST['db_key'], '', $_POST['db_port']);
if(!$db) {
exit('Error connecting to database'); //Should be a message a typical user could understand in production
}
$db_name = $_POST['db_name'];
$query = "CREATE DATABASE IF NOT EXISTS ?;";
$stmt->bind_param('s', $db_name);
$stmt = $db->prepare($query);
$stmt->execute();
I even tried:
$db = new mysqli($_POST['db_ip'], $_POST['db_user'], $_POST['db_key'], '', $_POST['db_port']);
if(!$db) {
exit('Error connecting to database'); //Should be a message a typical user could understand in production
}
$db_name = $_POST['db_name'];
$query = mysqli_prepare "CREATE DATABASE IF NOT EXISTS ?;";
mysqli_stmt_bind_param($query, 's', $db_name);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
last one added me a database but with the ? as name...
I hoped some one here can help me with that.

Not every SQL statement supports prepared statements. And CREATE DATABASE is one of them.
So, as a general rule, you are supposed to choose the database/table name from the white list.
In your specific case, however, when a user is apparently a database owner, there is not much point in protecting them from SQL injection as they apparently has the database password and can run any SQL statement much more convenient way. So you changed the code for nought. Just revert it back to the regular query() call.
I would only add backticks around the table name so it would always make a correct identifier name. And also may be add a regex validation just in order to avoid a human error.

Related

Why is the data not inserted into mysql database after submitting php nor is it giving out any error?

My code is below, I don't know what is wrong with my code, it says data submitted but not inserted into mysql database when I see in phpmyadmin
<?php
$dbhost = 'localhost';
$dbuser = 'Krishna';
$dbpass = 'xxxx';
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
session_start();
if (isset($_POST['submit'])){
if(! $conn ) {
die('Could not connect: ' . mysqli_error());
}
}
mysqli_select_db($conn, "krishna");
$sql = "INSERT INTO contact_us (name, email, sub, mess)
VALUES ('$_POST[name]','$_POST[email]','$_POST[sub]','$_POST[mess]')";
if(! $sql) {
die('Error: ' . mysqli_error());
}
echo "1 Record Added to Table\n";
echo "<a href='contactForm.html'>Back to main page</a>";
mysqli_close($conn);
?>
First let me start by saying you could do this in an attempt to learn how to use SQL which I also did when I was first learning but then realized ...
This method is subject to SQL injection attacks and should not be used. Directly taking any user input without sanitizing it first is critical mistake that can lead security vulnerabilities.
We now have tools like PDO statements which prepare your SQL for entry into a databases. Please consider using a similar tool which prepares your statements when getting anything from a user.
Users are not to be trusted. In the code below when you bindValue it takes the variable $id and removes anything harmful.
<?php
$stmt = $db->prepare("SELECT * FROM table WHERE id=? AND name=?");
$stmt->bindValue(1, $id, PDO::PARAM_INT);
$stmt->bindValue(2, $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
See this link for the source of the code above and a tutorial on PDO. There are probably better tutorials out there though.
http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers

Executing mysqli insert query then immediately selecting ID of new row

I've been spending a couple of hours trying to write mysqli queries to insert a new row in a database (with a primary key ID) and then select the ID of the new row. My code as it currently is:
<?php
include('connectionData.php');
$conn = mysqli_connect($server, $user, $pass, $dbname, $port)
or die('Connection error');
if(isset($_POST['submit'])) {
$pnum = $_POST['pnum'];
$phone_insert_text = "INSERT INTO `voterdatabase`.`phone` (`pnum`) VALUES (?)";
$phone_insert_query = $conn->prepare($phone_insert_text);
$phone_insert_query->bind_param('s', $pnum);
$phone_insert_query->execute();
$phone_select_text = "SELECT phone_id FROM voterdatabase.phone WHERE pnum=?";
$phone_select_query = $conn->prepare($phone_select_text);
$phone_select_query->bind_param('s', $pnum);
$phone_select_query->execute();
$phone_select_query->bind_result($phone_id);
echo $phone_id;
?>
$phone_insert_query executes without issue. But $phone_select_query doesn't appear to run at all, as echo $phone_id; has no effect. What might be going on here? I'm able to run the query directly in MySQLWorkbench.
Note that I previously tried doing this in one query using SELECT LAST_INSERT_ID();, but mysqli fails to execute any query containing that.
Please try this
$lastInsertID= mysqli_insert_id($conn);
Use insert_id property:
<?php
include('connectionData.php');
$conn = mysqli_connect($server, $user, $pass, $dbname, $port)
or die('Connection error');
if(isset($_POST['submit'])) {
$pnum = $_POST['pnum'];
$phone_insert_text = "INSERT INTO `voterdatabase`.`phone` (`pnum`) VALUES (?)";
$phone_insert_query = $conn->prepare($phone_insert_text);
$phone_insert_query->bind_param('s', $pnum);
$phone_insert_query->execute();
$phone_id = $conn->insert_id;
echo $phone_id;
?>
If you wish to be able to use the available functions to get the last inserted id, like mysqli_insert_id(), your table must have an AUTO_INCREMENT column. If not you will not get the id.
Also, even if you have the required columns, this will require two calls. To get around this, what you could do is something like create a stored procedure to do your insert for you and return the inserted id from the procedure.

MySQL query not fetching results (PHP)

I have the following script with an SQL problem which is not working.
<?php
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "Freepaste";
$conn = mysqli_connect($servername, $username, $password,$dbname);
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
$user = $_POST['user'];
$pass = $_POST['pass'];
echo $user." ".$pass;
$stmt = $conn->prepare("SELECT * FROM users where users.username= ? AND users.password = ?");
$stmt->bind_param('ss', $user, $pass);
$stmt->execute();
$result = $stmt->get_result();
printf("Errormessage: %s\n", $mysqli->error);;
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
echo "<br>id: " . $row["username"]." Password ".$row["password"]. "<br>";
}
}
else {
echo "<br>0 results <br>";
printf("Errormessage: %s\n", $mysqli->error);
}
mysqli_close($conn);
?>
The statement without the "where" clause gets me all the results, so I know the keys are right. Also, I ran the query in MySQL and it is working fine. I tried adding "" to $user and $pass, still not working. I checked the names in HTML, they are correct too. What am I missing?
Here's the link to the HTML:
http://pastebin.com/CWLuafVq
You are missing the quotes (although you are saying you tried) i think it should have worked. Your query should be:
SELECT * FROM users where users.username='$user' AND users.password='$pass'
Your query is vulnerable to SQL injection and in order to avoid it (and avoid hassle like requiring quotes in SQL statement), you should use PreparedStatement.
For your example, you just need to put single quotes around $user and $pass in the query.
BUT!!!!!! Your query is open to SQL injection. You should change the way you write queries. Use bound parameters instead, then you can almost forget about that issue.
Example:
$stmt = $conn->prepare("SELECT * FROM users where users.username= ? AND users.password = ?");
$stmt->bind_param('ss', $user, $pass);
$stmt->execute();
$result = $stmt->get_result();
See here for more information
As it stands, when your variables are put into the sql query, it ends up looking like this WHERE users.username=goelakash AN.... Without quotes around username and password, mysql is going to think you're comparing two columns.
What your query needs to look like is this.
$sql = "SELECT * FROM users where users.username=\"$user\" AND users.password=\"$pass\"";
Do yourself a huge favor, and put mysqli_error() calls after your calls to mysqli_query(). These will tell you exactly what mysql is crying about.
It is also worth noting that your queries are open to sql injection and you should take a look at prepared statements to mitigate that.
make sure your database password is 'root'? If yes then follow the query string
$sql = "SELECT * FROM users WHERE users.username='$user' AND users.password='$pass'";
just replace it. I think it will work fine :)

update mysql database table fields with a single mysqli statement query

I have a database table and i am updating the table columns this way.
$mysqli = new mysqli('localhost', 'root', '', 'db');
if (mysqli_connect_errno()) {
echo 'failed to connect to db.. <br>' . mysqli_connect_errno();
return 'error';
}
$username = $data['username'];
$data['image'] = $this->replace_whitespace($data['image']);
foreach($data as $key=>$value){
$this->query = "UPDATE users SET $key=? WHERE username='$username'";
$this->statement = $mysqli->prepare($this->query);
if($this->statement){
$this->statement->bind_param('s', $value);
$this->statement->execute();
$this->statement->close();
}
}
Is it possible to update more than one table columns in one go. I tried this but in-vain.
$this->query = "UPDATE users SET col1=?, col2=?, col3=? WHERE username='$username'";
$this->statement = $mysqli->prepare($this->query);
if($this->statement){
$this->statement->bind_param('sss', $value1, $value2, $value3);
$this->statement->execute();
$this->statement->close();
}
Is there a better way doing this?
$mysqli = new mysqli('localhost', 'root', '', 'db');
if (mysqli_connect_errno()) {
echo 'failed to connect to db.. <br>' . mysqli_connect_errno();
return 'error';
}
$username = $data['username'];
$this->query = "UPDATE users SET fname=?, lname=?, email=?, tpin=?, image=?, address=? country=?, city=?, state=?, postal=? WHERE username='$username'";
$this->statement = $mysqli->prepare($this->query);
if ($this->statement) {
$this->statement->bind_param('ssssssssss', $data['fname'],$data['lname'],$data['email'],$data['tpin'], $data['file'], $data['address'],$data['country'],$data['city'],$data['state'], $data['post_code']);
$this->statement->execute();
$this->statement->close();
}
This is my real code.
Remove the "," after col3=?
This will fix the syntax error
$this->query = "UPDATE users SET col1=?, col2=?, col3=?, WHERE username='$username'";
You have an extra comma, meaning your SQL is reading "WHERE" as another column and everything gets messed up.
$this->query = "UPDATE users SET col1=?, col2=?, col3=? WHERE username='$username'";
Should work fine.
In response to the comment below, this is the correct way of going about it, so it must be a faulty variable somewhere, what error messages are you getting? (If any)
It could also be that one of the parameters you are binding is not a string. Regardless, we'd need a more in-depth example.
Is it possible to update more than one table columns in one go
Yes. Actually, updating many fields in one query is a very core feature of any DBMS. You can always expect it to be supported.
I tried this but in-vain.
Well, you have to try more, like we all do. After all, it's your job.
Two notes regarding your "real" code:
You have to bind ALL variables in the query, not only some of them
you have to configure mysqli to report errors:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
I assume it works the same way as putting new values into the database.
Update a row mysql in php

Prepared statements and how they affect queries

In an effort to make my scripts more secure, I have started using prepared statements to prevent mysql injection. This script inserts the data just fine, but getting the last inserted id (based on auto incrementation in the database) now returns 0 when it should return the correct id number.
This part inserts just fine.
$stmt = $conn->prepare("INSERT INTO users (userName) VALUES (?)");
$stmt->bind_param("s", $_SESSION['username']);
$stmt->execute();
This is where I am having problems. I am trying to get the last inserted ID of the user and it is returning 0.
// Get the last inserted ID for the users ID
$query = "SELECT LAST_INSERT_ID()";
$result = mysql_query($query);
if ($result) {
$nrows = mysql_num_rows($result);
$row = mysql_fetch_row($result);
$userId = $row[0];
}
This was working when I had my script before starting on Prepared Statements. The only thing I changed was adding the Prepared Statement to insert the data and my db connection is as follows:
$conn = new mysqli($server, $user, $password, $database) or die('Could not connect: ' . mysql_error());
I am a noob with php so any help would be greatly appreciated.
You may have a fundamental misunderstanding: When you switch to mysqli, your mysql_* functions will no longer use the same connection.
LAST_INSERT_ID() works on a per-connection basis.
You will have to make that query using the same library/connection as the main query, or as #zerkms points out, use $conn->insert_id.
mysqli_insert_id().

Categories