I have a setup where I am deleting entries from a table.
It is based on the querystring of the URL which I'm thinking might be a bad way to start anyway.
So if the URL is:
http://www.example.com/delete.php?id=123&ref=abc
And the php in delete.php is as follows:
$id=$_GET['id'];
$ref=$_GET['ref'];
$con = mysql_connect("blahblah","user","password");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("test", $con);
mysql_query("DELETE FROM mytable WHERE id=" . $id . " AND ref='" . $ref . "'");
mysql_close($con);
Is there a way to make this more secure... or is this indeed in any way secure at all??
EDIT:
OK, so based on the feedback I've taken a new approach.
list.php contains a set of radiobuttons for each entry in the table - as follows:
$con = mysql_connect("localhost","username","password");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("db", $con);
$result = mysql_query("SELECT * FROM myTable");
echo "<form name='wer' id='wer' action='delete.php' method='post' >";
echo "<table border='1'>";
while($row = mysql_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['title'] . "</td>";
echo "<td><input type='radio' name='test1' value='" . $row['id'] . "' /></td>";
echo "</tr>";
}
echo "</table>";
echo "<input type='submit' name='submit' value='Submit' />";
echo "</form>";
mysql_close($con);
And delete.php looks like this:
function check_input($value) {
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
if (!is_numeric($value)) {
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}
$con = mysql_connect("localhost","user","password");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
$varID = check_input($_POST["id"]);
mysql_select_db("db", $con);
$sql="DELETE FROM myTable WHERE id IN (" . $varID . ")";
if (!mysql_query($sql,$con)) {
die('Error: ' . mysql_error());
}
mysql_close($con);
header("Location: list.php");
Is this a better way to go about it?
You have a SQL injection vulnerability since you don't sanitize the GET parameters you put into your query. The attacker can use that to delete all elements in your table.
The clean solution to this is using prepared Statements.
The quick and dirty solution is putting them in quotation marks and running them through mysql_real_escape_string.
Even if you fix that part, if the attacker can guess a valid id/ref pair he can delete that entry.
If a parameter is an integer, then why don't you make its type integer too? Something like $id=intval($_GET['id'])
GET is considered a safe method and should not have any side effects:
In particular, the convention has been established that the GET and
HEAD methods SHOULD NOT have the significance of taking an action
other than retrieval. These methods ought to be considered "safe".
In your case your script might be vulnerable to Cross-Site Request Forgery. You should better use POST instead and consider some kind of authentication and authorization check before deleting.
Additionally, since you use the passed parameters unaudited and unmodified, you are also vulnerable to SQL Injections.
At the very least, you should put these values into parameters instead of sticking them right into your SQL statement. Right now you are vulnerable to a SQL Injection attack. Here is a good article on how to parameterize your query, use a stored procedure, or validate the incoming statement. This should greatly help your security:
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
mysql_query(sprintf("DELETE FROM mytable WHERE id='%s' AND ref='%s'", mysql_real_escape_string($id),mysql_real_escape_string($res)));
Related
I am getting no where with this, I am not getting any output from my echo ,can someone help, thanks in advance...singhy
code below...
$strSQL = "SELECT * FROM <tablename> WHERE id='" . $_GET["serviceName"] . "'";
$rs = mysql_query($strSQL);
while($row = mysql_fetch_array($rs)){
echo "<dt>Name:</dt><dd>" . $row["serviceType"] . " " . $row["serviceName"] . "</dd>";
echo "<dt>Phone:</dt><dd>" . $row["Phone"] . "</dd>";
echo "<dt>Birthdate:</dt><dd>" . $row["BirthDate"] . "</dd>";
}
// Close the database connection
mysql_close();
?>
<p>Return to the list</p>
</body>
</html>
can someone tell me where i am going wrong, ive tried various options, thanks in advance, singhy
Try this debugging code:
$serviceName = mysql_real_escape_string($_GET['serviceName']); // Read PS note at the end
$strSQL = "SELECT * FROM `tablename` WHERE id='$serviceName'";
$rs = mysql_query($strSQL) or die(mysql_error()); // Display any query error
echo "Total number of rows: ". mysql_num_rows($rs); // Echo number of rows
while($row = mysql_fetch_assoc($rs)){
echo "<dt>Name:</dt><dd>" . $row["serviceType"] . " " . $row["serviceName"] . "</dd>";
echo "<dt>Phone:</dt><dd>" . $row["Phone"] . "</dd>";
echo "<dt>Birthdate:</dt><dd>" . $row["BirthDate"] . "</dd>";
}
Please note
You should escape the $_GET request and never use it directly in a query statement. Use mysql_real_escape_string() for that. (This method will be deprecated, read next bullet)
many of the functions you are using will be deprecated starting php 5.5.0 Alternatively you can use PDO prepared statements
replace
$_GET["serviceName"]
with this
$_GET['serviceName']
use single quotes in $_GET in your case.
This is a very noob question.
But I'm having an issue that I believe stems from this poorly written database query. I don't know if I'm not closing the connection or if closing the connection is necessary, but the server is indicating that it's timing out after about 60 seconds and it's causing a high resource usage. Could anyone tell me what's wrong with this query?
It's just a basic php query that pulls from the database.
<?php if(isset($_POST['submit'])) {
//print_r($_POST);
$example=$_POST['...'];
if ($job_number=="") { die("Nothing here.");
}
$con = mysql_connect("...","...","...");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("...", $con);
$query = "SELECT * FROM EXAMPLE WHERE job_number='$example' OR email='$example'";
$result = mysql_query($query);
if (mysql_num_rows($result) == "0") {
echo
'Nothing here.';
exit;
}
echo "<div class='sample'>";
while ($row = mysql_fetch_assoc($result)) {
//print_r($row);
//customer name
echo "<h2>" . $row['name'] ."</h2>";
//status
echo "<p>" . $row['status'] ."</p>";
}
echo "</div>";
}
mysql_close($con);
?>
To be honest there is a lot about databases you are not understanding.
Databases take time to read. The way they are indexed defines how you need to approach reading them.
Take a look at this Measuring actual MySQL query time
...and a few others.
I have a feeling your database is huge, and possibly badly structured. This is where I refer you to:
http://en.wikipedia.org/wiki/Database
There is a wealth of information here to clear your question up.
I'm able to display what I have in my table with the code below, but as you can see in the code I'm linking the rows to a new page, and on that page I'm trying to display the rest of the rows, which I have in the same table.
I mean, I have cols ID, photo, Firstname, Lastname, Age, StreetAdd, PhoneNum, EmailAdd in the table. I'm displaying only rows photo, Firstname, Lastname on the first page.
So what I'm trying to do is when the user clicks on the First name , which I displayed from the database, he will be redirected to the new page and see the rest of the info. How do I do it?
This is the PHP page which displays the three cols. I can display the rest of the cols on a new page but it's displaying all the info in the row. I want to display the individual info for each user, not the whole list. A possible example would be eBay. When you search for items, you won't see the full description until you click on the picture or the title.
<?php
$con = mysql_connect("localhost","root","");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("simple_login", $con);
$result = mysql_query("SELECT * FROM test ");
echo "<table align='center' bgcolor='#F9F0F0' border='0' cellspacing='0'>
<tr>
<th><font color='red'>Firstname</font></th>
</tr>";
while($row = mysql_fetch_array($result)) {
echo "<tr>";
echo "<td><a href='send.php'><img src='".$row['photo']."' \" width=\"150px\" height=\"150px\" /></a><br><br><br>";
echo "<a href='send.php'><td align='center' style='vertical-align:text-top' width='200px'>" . $row['Firstname'] . "</td>";
echo "<td align='center' style='vertical-align:text-top' width='200px'>" . $row['Lastname'] . "</td>";
echo "</tr>";
}
echo "</table>";
mysql_close($con);
?>
On you have put a text level element a inside a block level element td the cell where first name is shown. Also you didn't close a tag there. correct form is this.
echo "<td align='center' style='vertical-align:text-top' width='200px'>";
echo "<a href='send.php'>" . $row['Firstname'] . "</a></td>";
To get the same user bio on the send.php you need to pass the primary key for this row. For examle if the primary key is id you pass it send.php in query string.
echo "<a href='send.php?id=".$row['id']."'>" . $row['Firstname'] . "</a></td>";
Now in the send.php use $_GET['id'] to get the primary key and use it to retrieve the user bio from db.
But make sure you escape parameters you pass to sql database. Dont use those variables directly! See Nullpointer's answer
Update 1:
When you get the primary key of a row just invoke a SELECT * with LIMIT 1
$pkey = mysql_real_escape_string($_GET['id']);
$sql = "SELECT * FROM test where id='$pkey' LIMIT 1";
/* Run this sql */
to display individual info for each user you can use where close in query like
SELECT * FROM test WHERE user = bla
Warning
your code is vulnerable to sql injection you need to escape all get and post and the better approach will be using Prepared statement
Good Read
How to prevent SQL injection in PHP?
Are PDO prepared statements sufficient to prevent SQL injection?
Note
The entire ext/mysql PHP extension, which provides all functions named with the prefix mysql_, is officially deprecated as of PHP v5.5.0 and will be removed in the future. So use either PDO or MySQLi
Good read
The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead
Pdo Tutorial For Beginners
This should be your first page
<?php
$con = mysql_connect("localhost","root","");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("simple_login", $con);
$result = mysql_query("SELECT * FROM test ");
echo "<table align='center' bgcolor='#F9F0F0' border='0' cellspacing='0'>
<tr>
<th><font color='red'>Firstname</font></th>
</tr>";
while($row = mysql_fetch_array($result)) {
echo "<tr>";
echo "<td><a href='send.php'><img src='".$row['photo']."' \" width=\"150px\" height=\"150px\" /></a><br><br><br>";
echo "<a href='send.php?".$row['id']."'><td align='center' style='vertical-align:text-top' width='200px'>" . $row['Firstname'] . "</td>";
echo "<td align='center' style='vertical-align:text-top' width='200px'>" . $row['Lastname'] . "</td>";
echo "</tr>";
}
echo "</table>";
mysql_close($con);
?>
Now send.php should be
<?php
$con = mysql_connect("localhost","root","");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("simple_login", $con);
$sql = "SELECT * FROM test where id = " . $_Get['id'] ;
$result = mysql_query($sql);
//then display the result here
?>
hope this helps
I'm new to php and mysql so this I'm sure is very simple!
I would like to increment a specific entry depending on which button was clicked. The problem I am having is that I'm not sure how to tell mysql which entry to increment via php.
I'm using a while loop to display my table and then on the end of each row adding a button that has a name = $row[id] value = $row[likes]. If name was simply a word then it wouldn't be a problem but I need it to be different depending on the row it's in. (I'm using the row id the auto increments, I don't display it but it exists).
My .html:
$host="xxx";
$username="xxx";
$password="xxx";
$db_name="xxx";
$tbl_name="blog";
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
$result = mysql_query("SELECT * FROM $tbl_name ORDER BY id DESC");
echo "<table id='blog'>
<tr>
<th>Update</th>
<th>Likes</th>
</tr>";
while($row = mysql_fetch_array($result)) {
echo "<tr>";
echo "<td id='entry'>" . $row['entry'] . "</td>";
echo "<td id='like'>" . "<form action ='likes.php' method ='post'>" . "<input type='submit' name='$row[id]' value='$row[likes]' />" . "</form>" . "</td>";
echo "</tr>"; }
echo "</table>";
mysql_close($con);
?>
My .php:
<?php
$con = mysql_connect("xxx","xxx","xxx");
if (!$con) {
die('Could not connect: ' . mysql_error()); }
mysql_select_db("xxx", $con);
if(mysql_query("UPDATE blog SET likes = likes +1 WHERE id = '$_POST[$id]'")) {
header('location:blog.php'); }
else {
echo "Error: " . mysql_error(); }
mysql_close($con);
?>
All I want to do is link 'input name = $row[id]' in the html document with the WHERE id = $_POST[id] so that it will increment the like count on button click.
Thanks in Advance!!
Use a hidden input within the form to tell the PHP side which entry to increment.
echo "<td id='like'><form action ='likes.php' method ='post'><input type='hidden' name='id' value='" . (int)$row['id'] . "' /><input type='submit' name='submit' value='" . (int)$row['likes'] . "' /></form></td>";
The query line should be:
if(mysql_query("UPDATE blog SET likes = likes +1 WHERE id = '" . (int)$_POST['id'] . "'")) {
Notice I casted the IDs as (int), this prevents SQL Injection in the query, and prevents XSS when outputting.
The submit button is unreliable for the transportation of data, this is because in some situations not all browsers actually send the submit button as a POST/GET variable.
The other thing I noticed was the use of this syntax $row[likes] which should be:
$row['likes']
If you don't include quotes then PHP first treats likes as a constant and if not defined, falls back as a string.
I posted a couple days ago and I could not insert an additional record into a MySQL database I setup. I corrected the syntax, but the database will not update again. Basically, I have a couple forms in HTML that carry sessions over to the next pages until the PHP is processes on the final page to INSERT into the database. It worked twice (I have 2 records in the database now), but it won't insert any additional records. It worked fine a couple days ago. The only changes I made to anything was that I added a search feature that accesses the same database with the same user, but the connection is closed at the end of that script as well. Here is the code I am using to INSERT into the database (I know it isn't the best coding job, I'm still learning).
<?php
$con = mysql_connect("localhost","my_username","mypassword");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("dgibbo1_imaging", $con);
// Here too, please mysql_real_escape_string() all parameters
mysql_query("INSERT INTO imaging (os,MAC,Model,AntiVirus,Browser,Email,Connectivity,Sound,Ports) VALUES ('".$_SESSION['imaging2']."','".$_SESSION['imaging3']."','".$_SESSION['imaging4']."','".$_SESSION['antivirus']."','".$_SESSION['browser']."','".$_SESSION['email']."','".$_SESSION['connectivity']."','".$_SESSION['sound']."','".$_SESSION['ports']."')");
OR die("Could not update: ".mysql_error());
mysql_close($con);
?>
The name of the database is imaging. The columns are setup as:
id (This is the primary key field)
os
MAC
Model
AntiVirus
Browser
Email
Connectivity
Sound
Ports
I just find it odd that it inserted records without any problems until I tried it again today. Is it possible that it has something to do with my code for the search?
The search is a simple form on another page and processes this form:
<?php
$con = mysql_connect("localhost","my_user","mypassword");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("dgibbo1_imaging", $con);
// Always escape parameters injected into SQL queries
$result = mysql_query( "SELECT * FROM imaging WHERE MAC LIKE '%"
. mysql_real_escape_string ( $search, $con )
. "%'"
);
echo "<table border='1'>
<tr>
<th>MAC</th>
<th>Model</th>
<th>AntiVirus</th>
<th>Email</th>
<th>Browser</th>
<th>Connectivity</th>
<th>Sound</th>
<th>Ports</th>
</tr>";
while($row = mysql_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $row['MAC'] . "</td>";
echo "<td>" . $row['Model'] . "</td>";
echo "<td>" . $row['AntiVirus'] . "</td>";
echo "<td>" . $row['Email'] . "</td>";
echo "<td>" . $row['Browser'] . "</td>";
echo "<td>" . $row['Connectivity'] . "</td>";
echo "<td>" . $row['Sound'] . "</td>";
echo "<td>" . $row['Ports'] . "</td>";
echo "</tr>";
}
echo "</table>";
mysql_close($con);
?>
Meanwhile, the search will pull up the 2 existing records successfully every time, but I can't add new records and I'm wondering if it has something to do with this.
Thanks for any suggestions. I know my syntax probably isn't the best, so any suggestions from this site are always appreciated.
Try creating a separate php file and hard coding the values into it. Run that and see what happens. your search form shouldnt interfere with another form.
edit any errors when using the form? any errors when inserting to another table?
I saw your post, and it all looks "right". What I'd suggest is to add some logging instead of DIE and look at what MySQL is saying about those insert statements:
$sql = "INSERT INTO imaging ....";
mysql_query($sql);
if(mysql_errno()) {
$message = mysql_error() . "\n" . $sql . "\n";
$fp = fopen('c:\mylogifle.txt', 'a');
fwrite($fp, $message);
fclose($fp);
}
AND...as everyone has mentioned, encode those strings - assuming that the SQL is actually being executed, and you "know" it works, there's a very high possibility that some punctuation in one of the values is interfering with the SQL, like an unexpected comma somewhere that confuses MySQL