tags:

views:

273

answers:

6

I have the following code snippet to delete records from a database given a primary key. This is called via an AJAY request, through GET. Anyone who were to examine my javascript could work out the URL and delete arbitrary records. What can I do to prevent this?

Not use GET?

Use sessions?

if($cmd=="deleterec") {
    $deleteQuery = "DELETE FROM AUCTIONS1 WHERE ARTICLE_NO = ?";
    if ($delRecord = $con->prepare($deleteQuery)) {
     $delRecord->bind_param("s", $pk);
     $delRecord->execute();
     $delRecord->close();
     echo "true";
    } else {
     echo "false";
    }
}
A: 

Don't expose CRUD methods via Ajax.

Jan Jungnickel
What would be the reason?
Ionuț G. Stan
+2  A: 

You can give your records a non-sequential random unique id to use in AJAX requests.

Still not the most secure solution although should be easy to integrate into your current system.

Callum
+1  A: 
  1. Use post rather than get
  2. Embed hidden unique ids in any forms that will perform this action, and check that the id that comes back has been issued by you
  3. Obfuscate the URL/parameter names
  4. Generate unique IDs for the rows, and dont expose them externally, so an attacker cannot pick a row to delete.
Visage
It prevents googlebots accidentally submitting all the forms on your site and deleting stuff.
rikh
Yup. It also stops authenticatec users bookmarking dangerous urls that untrusted users may later use. It wont stop everything, but its a small step.
Visage
This is all security through obscurity. These techniques may prevent an honest user from poking around, but the question asked for a secure way to do it and this isn't it. See the other responses that say to authenticate and authorize before deleting.
GloryFish
No it isnt. Points 2 and 4 rely on server generated IDs that an attacker cannot generate or place on the server.
Visage
None of these methods really solve the problem. You need authentication pure and simple. You use this authentication to reduce what articles the user can delete.
gradbot
A: 

Well, if not everyone can delete a record, make sure this one is behind a password, so only the authorized users can do deletes. Make yourself a login that adds a 'Delete' button on the page afterwards and on the PHP side make sure the user is authorized when processing the commands.

Oh and yes, make sure you always pass a confirmation value through POST to validate, not just a GET parameter, it's best practice, even with authorized users.

lpfavreau
what do you mean by a confirmation value?
Joshxtothe4
Well, it's already a good thing if you post the ID of the record and something like confirmed=true to yourpage.php?cmd=delete. Imagine what would happen if only relied on a get parameter and that the URLS were publicly available; just Google while browsing through your page could delete all rows.
lpfavreau
But in any cases, it's not secure to have a delete command that will respond to any request from any user if not everyone can delete. Even if it's not exposed in your javascript, it's a security risk.
lpfavreau
And if it's open to everyone, just make sure you have a confirmation page that posts to the command, because it doesn't make any sense to "hide" it if people can delete anyway through normal functionality. Rule of thumb: when you modify the state of your DB, pass the values through a POST.
lpfavreau
+3  A: 

Not using GET won't change a thing. You have to use sessions to manage 'access control' before you even get to this point in the code.

That is to say, when the AJAX request is made you should at that point confirm via the session that the person making the request is allowed to do the delete, before actually doing it.

Think about how you would check permissions in a 'non-AJAX' way and do the same here.

Narcissus
Just like Narcissus said, treat the ajax call as if you had a nice UI around it just for the user. Just use a user auth GUID generated on login saved in a cookie to authenticate for deletion privileges.
gradbot
+1  A: 

There are two important aspect to your question.

Are authorized user supposed to be able to delete any record they see fit? If that's the case your issue is one of making sure the request came from an authorized user. In that case using PHP's session is one way of making sure that it's the user you authenticated that made the request. Of course, with all technologies you have to make sure you use PHP session the right way. There are a bunch of articles on that mather. PHPsec.org has one here.

If a user cannot delete any row, in addition to doing authentication and sessions you'll also need to had a check in your code for the verify if the record being deleted can be deleted by that user. Now this is highly dependant on your application. For example, in a project management software, one could be allowed to delete tasks associated with one project but not with another one. That's part of your business logic.

The best would be to perform both check. One, your application must verify if the user making the deletion is a valid user and is allowed to delete (very simple to implement with php sessions) and two make sure that the user can delete the specific record based on some form of ownership.

Pierre-Luc Simard