In addition to the information that the user wishes to delete a record, you
should have, at a minimum, a unique session id associated with that user's
session, correct?
So, pass that session id, compare it to the current session id, and also keep a
record in the session of all the records the user has requested be deleted.
So, your URL goes from:
mypage.asp?delete=1
to
mypage.asp?delete=1&record_key=12345&session_id=@@@@1234567890@@@@
In your ASP you do something like (I don't work in ASP so I don't know how to
retrieve the current Session id, so this is JScript psuedo-code):
if (!Session['deleted']) {
Session['deleted'] = {};
}
if (!Session['deleted']['table_name']) {
Session['deleted']['table_name'] = {};
}
var recordKey = Request.Value('record_key');
if ((+Request.Value('delete') == 1) &&
Request.Value('session_id') == Session.ID &&
!Session['deleted']['table_name'][recordKey]) {
// delete the record
Session['deleted']['table_name'][recordKey] = true;
}
Now if someone tries to reload the same URL twice within the same session, it
fails because you've recorded a change in the table matching some unique value
within that table.
If someone tries to E-mail that URL to someone else, even if the other person
can actually log into your system and establish a session, it will have a
different session id than the session id on the URL and the delete will fail.
Someone might know how to find their current session id and change the URL to
reflect their session id, so you could add:
mypage.asp?delete=1&record_key=12345&session_id=@@@@1234567890@@@@&ts=<currentTimeInMilliseconds>
Then in your page you could test that timestamp against the current time on the
server, if it's different by more than say, 5 minutes, don't allow the delete.
Again, someone might know what the additional parameter is for and attempt to
change it so they can still delete the record, so if you want additional
security, encode the session_id on the URL using RC4 and some passphrase known
only to your ASP code, that would make it much more difficult for the end user
to "spoof" the session id and hijack the session.
I've got a page where some important data is concatenated with strings of
various length containing random characters inserted at fixed points within the
important data. The resulting string is then RC4 encoded on the URL using
REMOTE_USER, a value from the server system clock with it's accuracy reduced to
only 30 minutes plus an additional "secret" phrase. This means that the URL
produced is valid only for that user, for that session and for a period of 30
minutes from when I generate the page containing the link.
Admittedly this is still not completely secure, but I have a fair amount of
confidence that the resulting RC4 string can not be successfully decoded and
used within the same timeframe as the link is valid for. And considering
REMOTE_USER is a result of server authentication, they'd have to have hacked the
person's account before they could even begin to reverse engineer the URL. As
well, if a user attempts to E-mail the URL to someone else, and that someone
else authenticates against the server under their own username, the URL will not
decode properly and it simply won't work.
In other words, the solution you are looking for is not a client-side JavaScript
solution. The solution you are looking for is to do something on the server that
completely prevents the same user from doing the same thing during the same
session. In addition, you should think of the situation another user
deliberately (or accidentally) obtains a valid URL (containing the right session
id, the right timestamp, etc) and prevent _them_ from doing that task as well.
Using POST is simply _not_ secure and not a safe replacement for GET. I can
write a C# application in a few minutes that would repeatedly POST:
http://yourserver/mypage.asp?delete=1&record=1 (then 2, 3, 4, 5, 6...). You
_must_ validate the incoming information against what you already know about the
user, what they have the ability to do and what they have already done.