简体   繁体   中英

How do i make $_GET more secure.?

I am using the get method to perform some operation like, approve, markasspam, delete, for commenting system. i know it is highly insecure to go this way but i cannot help it out. because the reason for using $_GET method is to perform the operation within the page itself using PHP_SELF, and FYI i am using the post method using checkbox to perform the operation too.

now for making it bit secure i want to randomize the number or generate the hash or something and then compare it, get the id and perform the operation

my current code is somewhat like this.

<?php 
if($approve == 1 ) 
{ 
    ?>
    <a href="<?php echo $_SERVER['PHP_SELF']."?approve=".$id; ?>">Unapprove</a>
    <?php 
} else 
{ 
    ?> 
    <a href="<?php echo $_SERVER['PHP_SELF']."?unapprove=".$id; ?>">Approve</a>
    <?php 
}
?> 
| <a href="<?php echo $_SERVER['PHP_SELF']."?spam=".$id; ?>">Spam</a> 
| <a class="edit-comments" href="edit-comments.php?id=<?php echo $id; ?>">Edit</a> 
| <a href="<?php echo $_SERVER['PHP_SELF']."?delete=".$id; ?>">Delete</a>

and i perform the operation using this code..

if(isset($_GET['approve'])) {
    $id = intval($_GET['approve']);
    $query = "UPDATE comments SET approve = '0' WHERE id = '$id'";
    $result = mysql_query($query);
}

if(isset($_GET['unapprove'])) {
    $id = intval($_GET['unapprove']);
    $query = "UPDATE comments SET approve = '1' WHERE id = '$id'";
    $result = mysql_query($query);
}

if(isset($_GET['delete'])) {
    $id = intval($_GET['delete']);
    $query = "DELETE FROM comments WHERE id = '$id'";
    $result = mysql_query($query);
}

if(isset($_GET['spam'])) {
    $id = intval($_GET['spam']);
    $query = "UPDATE comments SET spam = '1' WHERE id = '$id'";
    $result = mysql_query($query);
}

instead of using approve or unapprove or delete or spam, i want to randomize or hash that words and want it as lengthy as possible and then perform the operation.

how do i do it? what is your take on this?

EDIT: Please Note Only the Authenticated User ie Admin will be able to perform this operation. even though it pass through authentication system i want to add more security even for admin. to avoid experiments or accident

the code is not exact it is just the sample to make you understand what i want to achieve.

Whether you use GET or POST parameters here doesn't matter much in this context - what the script needs first is some sort of authentication. (After that is done, you can go into security details where GET is slightly less secure than POST - see the comments for details.)

I'd say you have two options:

  • Protecting the entire script using .htaccess - no changes needed to the script itself

  • Introducing PHP side user authentication and perform the operations only if a logged in user makes the request. Needs fundamental changes to the script but is most flexible.

Re your edit:

It turns out your script is already protected. In that case I assume you are uncomfortable with incremental ID numbers turning up in the URLs, getting cached in the browser etc. etc. The usual solution to that is to generate a random key for each comment when it is created (in addition to the incremental ID). That key gets stored in a separate column (don't forget to add an index) and you'd match against that.

A step even further would be to create temporary hashes for every action, which is the ultimate protection against a number of outside attacks.

Re your edit about using one-time hashes:

I've never implemented one-time hashes in an admin interface yet so I have no experience with this, but I imagine that a very simple implementation would store action hashes in a separate table with the columns hash , record and action . Whenever your tool lists a number of records and outputs "delete / approve / unapprove" links, it would generate three record in the hash table for each comment: One for delete, one for approve, one for unapprove. The "delete / approve /unapprove" links would then, instead of the record ID and command, get the correct hash as the only parameter.

Add a time-out function for unused hashes (plus delete any hashes that were actually used) and you're done.

You can do it that way, the $_GET is not the unsecure thing in your code. The unsecurity comes from you not checking wether the user is eg authorized to delete comments.

In your current code, anyone can delete anything at anytime and as often as they want.

If you have a wrapping code that ensures the if-statements postet by you are not executed if enter good reason here , then it's okay.

But you should try verifying, that the content of the parameters are really integers instead of just int_val'ing them and using them directly on the database.

On your edit

You should check your parameter is really an int. intval("test") will also return an integer, mostly 0.

You might consider regex for that, to verify the string only consists of numbers: preg_match('/[0-9]+/', $_GET['id']);

If so, you can perform the action.

You shouldn't use GET for any operations that change data on server. NEVER. You use it only to get data.

If you can't use forms for operation buttons (because there is another form outside them) you should consider this design:

  • You use AJAX to perform POST requests to your server
  • In javascript-disabled environments you use GET links like user.php?action=delete, which shows you very simple form on a separate page. The header in the form asks: "Are you sure you want to delete user X?" and it has two buttons: 1) "Yes" - that submits POST request to operation script, 2) "No" - which sends user back to the page where he has been

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM