php MySQL CRUD: Am I deleting safely?

56

I am trying to determine the safest way or best practice to go about Deleting in a CRUD using php and MySQL. The way I was taught was to create<a href="delete.php=?{$id}">Delete</a> link and have delete.php run mydelete() method on the id passed in the$_GET variable.

  1. If I allowed a web crawler to see this page couldn't it delete the entire database if it crawled each delete link on each page?

  2. Couldnt someone who somehow figured out the page that callsdelete() manually load the url with whatever number they wanted to in the$_GET and delete records?

  3. Is it better to never delete anything through the CRUD but to add a Deleted column to the table and make it appear as though it has been deleted to the user?

  4. Am I just paranoid?

881

Answer

Solution:

If I allowed a web crawler to see this page couldnt it delete the entire database if it crawled each delete link on each page?

Yes.

Couldnt someone who somehow figured out the page that calls delete() manually load the url with whatever number they wanted to in the $_GET and delete records?

Yes.

Is it better to never delete anything through the CRUD but to add a Deleted column to the table and make it appear as though it has been deleted to the user?

If you actually want to delete it, imo, deleting is better.

Am I just paranoid?

Not at all.


If you just had a delete.php script that had something like the following (ignoring CRUD atm and talking about MySQL):

$q = "DELETE FROM mytable WHERE row = $_GET['id']";
$r = mysql_query($q);

Then yes, your first two concerns are actually what would happen. A spider who stumbled upon these links would cause DB records to be deleted and a malicious user who discovered the links could similarly delete rows from the DB.

This is usually handled two ways:

  1. Don't offer the delete.php link to people who shouldn't have it (people who are not logged in, people who are not logged in as admins, etc.) -- but note this is just a nicety and doesn't protect your DB from accidental / malicious deletion.

  2. In the delete.php script, verify that the person running it is allowed to delete rows. Most of the time is done by checking session variables that were set upon login (e.g.if($_SESSION['can_delete'] != true){ die('Insufficient Privileges'); }).

Although it is helpful not to offer the delete.php link to people who shouldn't have it, you need to explicitly check for permissions in the delete.php script if you want it to be secure.

948

Answer

Solution:

Read The Spider of Doom.

You can use a link to delete things, but the link should never be publicly exposed where it could be crawled, or even crawled by an internal indexing spider. Instead, you must check user authorization on every delete action to be sure the user making the deletion owns or is otherwise authorized to modify it.

So yourdelete() method must do more than just make the deletion (or the controller script which callsdelete()). Always check for user authorization before performing any modification or deletion.

Whether you actually perform a deletion or simply mark rows as deleted depends on whether or not you need your application to be able to undelete them. Either way, check for authorization before acting.

426

Answer

Solution:

  1. Yes. This has happened to a fair bit of people, google crawls a "delete" page and remove their contents. I remember there being a really good blog post about it, but can't seem to find it.

  2. Yes, this is entirely possible and very easy to do. That's why you need to build an authorization system. This means that before anything is performed, the system should check whether the user is allowed to do what he has requested, before performing the action.

  3. Again, this dependings. If there is no use for the data anymore, then by all means delete it and get rid of it. But if you want to support some sort of "undeleting", then just mark the item as deleted.

  4. No :)

38

Answer

Solution:

One simple way would be to initiate a session like:

$somevar = 'abc123'
$_SESSION['secureDelete'][$id] = $somevar;

and then print this:

<a href="delete.php?id={$id}&action={$somevar}">Delete</a>

When you want to delete the file you check if that session exists with that $somevar value:

if (isset($_SESSION['secureDelete'][$id]) && $_SESSION['secureDelete'][$id] == $_GET['action']) {
  deleteFunction($_GET['id']);
}
775

Answer

Solution:

Try using POST method and hide the ID, it should be like this

<form action="" method="POST">
<input type="hidden" name="id" value="<?= $id; ?>"/> 
<button type="submit">Delete</button> 
</form>

People are also looking for solutions to the problem: How can I preserve multidimensional array information when performing array intersections in PHP?

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.