Hi,
I’m using Ajax and PHP for a CRUD application. I show records I get from database in a html table, each record has a unique ID and I pass it to the html table storing it in the ID field then I can pass the value with Ajax and execute all the CRUD operations. The problem is that anybody using the browser developer tools could change the ID value in the html and then delete other users records for example.
What is the best approach to prevent this happening? So far I’ve put some more controls in the SQL query setting a where clause with the record ID and the user ID which is stored into a SESSION in this way the user can only delete his own records only. Do you think I could also store both the plain record ID and an encrypted record ID (maybe as value in html) and the see if they match during server side validation? Any other approach or ideas? Many thanks for your support as always.
Hi,
First, make users log in to your app. Then implement some kind of role-based access system, specifying permissions for who may do what.
As you are seeing, more or less anything client-side can be spoofed, so the access checks need to happen on your server.
Hi yes there is a login in place as well.
I need to have all the users able to delete records but only their own.
Then check that this is the case before performing the delete.
Presumably you use a cookie or JWT to track the user’s logged in status - you can just query that before deleting anything.
I personally check the backend to see if they are logged into or not with their credentials. (That is 99.9 percent of time handled by the backend application) If they match then onward the script goes otherwize it’s back to the home page the script goes.
Hi Yes this is what I do but if they are logged and change the id using developer tools they can delete other users records
That shouldn’t really be possible.
Imagine the user logs in and you set a cookie containing some way to identify them, e.g. their user ID.
They then attempt to send a delete request to your server to delete a record.
Your endpoint receives the request, retrieves the record to be deleted, then compares the ID of that record with the user ID from the cookie.
If the two match, then the delete is performed.
Otherwise the server responds with a 401 (and deletes nothing).
If you use HTTP-only cookies, they are not available in JavaScript making them pretty difficult to tamper with on the client.
I store the user ID into session.
Ok I understand, so I should perform two database queries one to retrieve the record and then if there is a match another query to delete it. I was hoping to only perform one database query
That’s what I would do. A second query seems a small price to pay if it stops users deleting other user’s records.
Provided you have done this securely (a prepared query) so that it cannot be bypassed by having sql as part of either of those two values, this is enough to limit the operation to just the ‘owner’ of the data.
BTW - in real applications, data is almost never actually deleted. If someone thought the data was important enough to insert, it is important enough that should it accidentally get deleted, it can be recovered. You would typically just UPDATE a ‘status’ column with a value that indicates the data is deleted/not used, then exclude the data in normal operations (a database table ‘view’ comes in handy for ‘automatically’ doing this.).
Yes I always use prepared statement and also sanitise the parameters as extra security. When the user tries to delete another user record it doesn’t get deleted but the query still return true.
Thanks for this as well I never thought about it.
The query was a successful query, i.e. no errors, but it didn’t affect any row(s). Assuming you are using the PDO database extension, the rowCount() method would return zero.
Yeeeah, I’d be careful with that. In Europe at least, there is a small thing called GDPR which says otherwise.
So your original method worked, but returned true when you didn’t expect it to?
Yes I’m using PDO. Perfect that is exactly what I need to send a message back to the user. Many thanks
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.