PHP update table by form - php

I'm trying to update a table from a form.
I have 3 pages. The first one queries all of the rows from my table with an "edit" link.
When edit is clicked (page 2) the code pulls the $id and puts it in the url. The $id is pulled from the url and is used in a query to fill a form.
My problem is passing the updated form info to my table. Basically the update isn't happening.
Second page
<?php
include '../db/config.php';
include '../db/opendb.php';
$id = $_GET["id"];
$order = "SELECT * FROM tableName where id='$id'";
$result = mysql_query($order);
$row = mysql_fetch_array($result);
?>
<form method="post" action="edit_data.php">
<input type="hidden" name="id" value="<?php echo "$row[id]"?>">
<tr>
<td>Title</td>
<td>
<input type="text" name="title" size="20" value="<?php echo"$row[title]"?>">
</td>
</tr>
<tr>
<td>Post</td>
<td>
<input type="text" name="post" size="40" value="<?php echo
"$row[post]"?>">
</td></tr>
<tr>
<td align="right">
<input type="submit" name="submit value" value="Edit">
</td>
</tr>
</form>
third page
include '../db/config.php';
include '../db/opendb.php';
$query = "UPDATE tableName SET '$_POST[title]', '$post[post]' WHERE id='$id'";
mysql_query($query);

It should be
UPDATE tableName SET `title` = {$_POST['title']}, `post` = {$_POST['post']}...
Ask yourself, what are you setting?

Your SQL statement for the database update is wrong. It should include a listing of not only the new values but also the corresponding field names. This means it should look more like this:
$query = "UPDATE tableName SET `title` = {$_POST['title']}, `post` = {$_POST['post']} WHERE id = '$id'";
Notice that you also should embrace fields of $_POST inside of strings with curly brackets ({}) or put them outside of the quotes. (like " = " .$_POST['title']. ", "). This is absolutely necessary if you use the standard way to access those with he quotes (e.g. not $_POST[title] but $_POST['title'] or $_POST["title"]).
Additionally you should add the following to your code:
Some error handling, currently you don't even know if something went wrong. The simplest way is to check the return value of the mysql_query() function for null and if it is null, get the mysql error message with mysql_error().
Escaping for passed values. Currently you directly pass the posted data into a mysql query which is very insecure. (See for example SQL-Injection on wikipedia) You should use mysql_real_escape_string() on all form data before inserting them into queries. This escapes all parts that could be malicious.

if (isset($_POST[title])){
$title = mysql_real_escape_string(trim($_POST['title']));
}else{
$title = NULL;
}
if (isset($_POST[post])){
$post = mysql_real_escape_string(trim($_POST['post']));
}else{
$post = NULL;
}
$query = "UPDATE tableName SET title='$title', post='$post' WHERE id='$id'";
mysql_query($query);
I would also recommend mysqli functions instead of mysql and I probably wouldn't call a variable and table column 'post' to avoid confusion.

That is because you are not setting the values. In the statement:
$query = "UPDATE tableName SET '$_POST[title]', '$post[post]' WHERE id='$id'";
you should pass column names to be updated.

If you are not using PDO statements yet to prevent SQL injection attacks then you should use more protection then just mysql_real_escape_string(). On top of escaping the data you should be validating that the submitted data is in fact what you are expecting.
Ie. In your code here:
$id = $_GET["id"];
$order = "SELECT * FROM tableName where id='$id'";
$result = mysql_query($order);
$row = mysql_fetch_array($result);
If you added:
if(is_numeric($_GET['id'])){
$id = mysql_real_escape_string(trim($_GET["id"]));
$order = "SELECT id, title, post FROM tableName where id='$id'";
$result = mysql_query($order);
$row = mysql_fetch_array($result);
}
This would at least validate what you are executing is in fact an ID number (That is, if ID is actually a number ;) . You can apply this logic to all your inputs if you are not yet using PDO statements. If you are expecting letters then validate for letters, numbers validate for numbers, escape special characters. Again, this is bare minimum. I would really suggest reading up on the hundreds of SQL injection techniques and start reading up on PDO's.
Also, in regards to using the SELECT * statement. I would try and avoid it. It adds a layer of vulnerability to your statements, if you change the order of the fields in your table and you are using $row[0] (Numbered requests) it can muck things up and lastly if your table contains additional fields with data that is unrelated to the ones you need then you are using on this page then you are loading information you don't need to.
$order = "SELECT id, title, post FROM tableName where id='$id'";
Would solve that nicely. :) Good luck!

Related

Is there a way to use a variable in a MySQL update query

Let's say I have a form like this
<?php include 'file2.php' ; ?>
<form action="file1.php" method="POST">
<input type="hidden" name="LHS" value="column1">
<input type="hidden" name="RHS" value="row">
<button type="submit">Submit</button>
</form>
and I have an update query in file2.php like this
$lhs = $_POST['LHS']
$rhs = $_POST ['RHS']
$update = "UPDATE table1 SET
column1 = '".$rhs."'
WHERE id = '".$_SESSION['id']."'";
mysqli_query($conn, $update);
So my questions is how can I use a variable($lhs) in place of "column1" to update mysql data
I have tried $table1['column1'] method too, but it only seems to work on Rhs side but not the LHS
Most Importantly: Your query is open to SQL Injection related attacks. Please learn how to use Prepared Statements
Also, it seems that the value of your $lhs variable is a Reserved keyword in MySQL. It is incidentally your column name as well. So, you need to use backticks (`), asking MySQL to consider it as a column/table/database name or some aliased expression.
Now, just do the following, to use $lhs as a column in the Update query:
$update = "UPDATE table1 `" .
$lhs . "` = '" . $rhs . "'
WHERE id = '".$_SESSION['id']."' ";
mysqli_query($conn, $update);

FIND a column name with a PHP variable on DATABASE and print the content

I work on a PHP file, and I want with one variable($time) to FIND a column on my database and print the content of the "$time" column, but I can't find the right syntax. In the end, it prints the $_GET['time'] I have passed and not the content of the column. Here is my code:
$id = $_GET['id'];
$time = $_GET['time'];
$query1 = "SELECT "."'$time'"."FROM uploads
WHERE station_id="."'$id'";
$result =mysqli_query($conn,$query1) or die(mysql_error());
$row = mysqli_fetch_array($result, MYSQLI_ASSOC) or die(mysql_error());
echo json_encode($row);
Any help or though???
First of all, your query is horrible and incredibly vulnerable to injection.
You need to rethink your dB design.
But to answer your question, it's probably because the way you're putting the variable in the statement.
Instead of:
$query1 = "SELECT "."'$time'"."FROM uploads WHERE station_id="."'$id'";
Change it to:
$query1 = "SELECT ". $time ."FROM uploads WHERE station_id=".$id;
Please rethink your database design as you have a Huge vulnerability

Get subject from Table in PHP

OK So I'm trying to access a table called emg_quote I have the Quote ID so Im trying to get the Column Subject from the same row as this ID but for some reason All I'm getting is the first row in the entire table? Can any one figure out what I'm doing wrong? Here is my coding:
$row['quote_id'] = quoteTitle($row['quote_id']);
function quoteTitle($quoteid){
global $db;
$sql = "SELECT subject FROM emg_quote WHERE ".$quoteid."";
$res = $db->query($sql);
$row = $db->fetch_row();
$output = $row['subject'];
return $output;
}
Are you using a custom object to wrap the native API's?
Either way it doesn't look right to me. You don't seem to be using the result of the query.
i.e.
$result = $mysqli->query($query);
$row = $result->fetch_row();
You have few bad practices in your code.
A. You lie on $quoteid to give you the correct where syntax. ie: ID=123
This is an highly unsafe method, because the user can change the it to Some-Important-Details='bla'
To extract more details from this table or others.
B. You should ALWAYS escape characters when receiving data from user, otherwise you easily subjected to SQL-Injections. And believe me you don't want it.
you have to use the checking after where.
use you column name before your $quoteid variable
$row['quote_id'] = quoteTitle($row['quote_id']);
function quoteTitle($quoteid){
global $db;
$sql = "SELECT subject FROM emg_quote WHERE quoteid=".$quoteid." LIMIT 1 ";
$res = $db->query($sql);
$row = $db->fetch_row();
$output = $row['subject'];
return $output;
}
Remember : USE limit 1 when you search with primary key and you know that only 1 record will be searched. it reduce your processing time.
You might be missing the where column.
$sql = "SELECT subject FROM emg_quote WHERE quote_id=".$quoteid."";
^^^^^^^^
We also do not see weather something with your Db class is wrong.
You should in any case not directly put request variables into a database query.
$sql = "SELECT subject FROM emg_quote WHERE ID='".$quoteid."'";
You had not wrote your db fieldname in where condition

MYSQL - INSERT error, unknown column in field list

i keep getting the following error from this simple mysql statement and i cant see why. im sure its something obvious.
require_once("connect.php");
$query = mysql_query("SELECT * FROM accounts ORDER BY id DESC LIMIT 1");
$row = mysql_fetch_assoc($query);
$balanceold = $row['balance'];
$difference = $_POST['predec'].".".$_POST['dec'];
$category = $_POST['category'];
$notes = $_POST['notes'];
if(isset($_POST['in'])){
$balancenew = $balanceold + $difference;
$query = mysql_query("INSERT INTO accounts(currentbalance, balancein, category, notes) VALUES (".$balancenew.", ".$difference.", ".$category.", ".$notes.")");
if($query){
header("Location: budget.php");
}
else{
die(mysql_error());
}
}
gives error:
Unknown column 'payday' in 'field list'
here is my form code:
<form action=process.php method=post>
£
<input type=text name=predec size=7>
.
<input type=text name=dec size=4 value=00>
<br />
<select name=category>
<option value=payday>Payday</option>
</select>
<input type=text name=notes size=20>
<input type=submit name=in value=Deposit>
<input type=submit name=out value=Withdraw>
</form>
database table"accounts" contains the following fields:
id, int primary A_I
balancein, decimal 10,2
balanceout, decimal 10,2
current balance, decimal 10,2
category, varchar 50
notes, varchar 255
date, timestamp
...in that order
try this (enclose each variable inside query with single quota):
mysql_query("INSERT INTO accounts(currentbalance, balancein, category, notes)
VALUES ('$balancenew', '$difference', '$category', '$notes')");
Its better to use mysqli or PDO to prevent from SQL injection attack, you could use mysql_real_escape_string() for now:
$balancenew = mysql_real_escape_string($balancenew);
and for other variables.
Thats because you have syntax error in your INSERT query. String and Date values are to passed into single quotes and not double quotes in sql. the . or the String concatenation character is also not required. So based on the data you provided it might be
$query = mysql_query("INSERT INTO accounts(currentbalance, balancein, category, notes)
VALUES ($balancenew, $difference, '$category', '$notes')");
Basically what sql is telling you that you are referencing a column in your insert that is not defined in the database. Provide your table structure or ensure that the column name is exactly as you defined in the db. HTH.
You have missed single inverted commas enclosing $notes and $category I guess. Enclose them in ' and your problem should be solved.

How do I demonstrate a Second Order SQL Injection?

So I've been trying to replicate a second order SQL Injection. Here's an example template of two php based sites that I've prepared. Let's just call it a voter registration form. A user can register and then you can check if you're a registered voter or not.
insert.php
<?php
$db_selected = mysql_select_db('canada',$conn);
if (!db_selected)
die("can't use mysql: ". mysql_error());
$sql_statement = "INSERT into canada (UserID,FirstName,LastName,Age,State,Town)
values ('".mysql_real_escape_string($_REQUEST["UserID"])."',
'".mysql_real_escape_string($_REQUEST["FirstName"])."',
'".mysql_real_escape_string($_REQUEST["LastName"])."',
".intval($_REQUEST["Age"]).",
'".mysql_real_escape_string($_REQUEST["State"])."',
'".mysql_real_escape_string($_REQUEST["Town"])."')";
echo "You ran the sql query=".$sql_statement."<br/>";
$qry = mysql_query($sql_statement,$conn) || die (mysql_error());
mysql_close($conn);
Echo "Data inserted successfully";
}
?>
select.php
<?php
$db_selected = mysql_select_db('canada', $conn);
if(!db_selected)
die('Can\'t use mysql:' . mysql_error());
$sql = "SELECT * FROM canada WHERE UserID='".addslashes($_POST["UserID"])."'";
echo "You ran the sql query=".$sql."<br/>";
$result = mysql_query($sql,$conn);
$row=mysql_fetch_row($result);
$sql1 = "SELECT * FROM canada WHERE FirstName = '".$row[1]."'";
echo "The web application ran the sql query internally=" .$sql1. "<br/>";
$result1 = mysql_query($sql1, $conn);
$row1 = mysql_fetch_row($result1);
mysql_close($conn);
echo "<br><b><center>Database Output</center></b><br><br>";
echo "<br>$row1[1] $row1[2] , you are a voter! <br>";
echo "<b>VoterID: $row[0]</b><br>First Name: $row[1]<br>Last Name: $row[2]
<br>Age: $row[3]<br>Town: $row[4]<br>State: $row[5]<br><hr><br>";
}
?>
So I purposely made this vulnerable to show how second order SQL Injection works, a user can type in a code into the first name section (where I am currently stuck, I've tried many different ways but it seems that I can't get it to do anything).
Then when a person wants to activate the code that he has inserted in the first name section, all he needs to do is just type in the userID and the code will be inserted.
For example:
I will type into the insert.php page as:
userid = 17
firstname = (I need to inject something here)
lastname = ..
age = ..
town = ..
state = ..
Then when I check for my details, and type in 17, the SQL script injected will be activated.
Can I get few examples on what sort of vulnerabilities I can show through this?
What is there to demonstrate?
Second order SQL injection is nothing more than SQL injection, but the unsafe code isn't the first line.
So, to demonstrate:
1) Create a SQL injection string that would do something unwanted when executed without escaping.
2) Store that string safely in your DB (with escaping).
3) Let some other piece of your code FETCH that string, and use it elsewhere without escaping.
EDIT: Added some examplecode:
A table:
CREATE TABLE tblUsers (
userId serial PRIMARY KEY,
firstName TEXT
)
Suppose you have some SAFE code like this, receiving firstname from a form:
$firstname = someEscapeFunction($_POST["firstname"]);
$SQL = "INSERT INTO tblUsers (firstname) VALUES ('{$firstname }');";
someConnection->execute($SQL);
So far, so good, assuming that someEscapeFunction() does a fine job. It isn't possible to inject SQL.
If I would send as a value for firstname the following line, you wouldn't mind:
bla'); DELETE FROM tblUsers; //
Now, suppose somebody on the same system wants to transport firstName from tblUsers to tblWhatever, and does that like this:
$userid = 42;
$SQL = "SELECT firstname FROM tblUsers WHERE (userId={$userid})";
$RS = con->fetchAll($SQL);
$firstName = $RS[0]["firstName"];
And then inserts it into tblWhatever without escaping:
$SQL = "INSERT INTO tblWhatever (firstName) VALUES ('{$firstName}');";
Now, if firstname contains some deletecommand it will still be executed.
Using a first name of:
' OR 1 OR '
This will produce a where clause in the second SQL of
WHERE FirstName = '' OR 1 OR ''
Therefore the result will be the first record in the table.
By adding a LIMIT clause, you can extract all rows from the table with:
' OR 1 ORDER BY UserID ASC LIMIT 0, 1 --
Obviously it will only extract 1 row at a time, so you would need to repeat that and increment the 0 in the LIMIT. This example uses a comment -- to terminate the remaining SQL which would otherwise cause the query to fail because it would add a single quote after your LIMIT.
The above is a simple example, a more complex attack would be to use a UNION SELECT which would give you access to the entire DB through the use of information_schema.
Also you are using addslashes() in one of your queries. That is not as secure as mysql_real_escape_string() and in turn: escaping quotes with either is not as secure as using prepared statements or parameterised queries for example in PDO or MySQLi.

Categories