Pass important values server-side when processing form

To be honest I think this question is off topic, because its topic is so a general concept that can apply to any language capable to handle web development. So is even broader than a general PHP question.

By the way, what I want to suggest is too much for a comment.

When you need to check data coming from trusted users (assuming you already have a way to check if an user is trusted) is to put in place a system for data integrity check.

A simple example. Assuming you have a form like:

<?php $data = get_my_form_data(); ?>
<form method="post">
    <input type="hidden" name="postid" value="<?= $data['postid'] ?>">
    <input type="text" name="vote" value="<?= $data['vote'] ?>">
    <input type="text" name="username" value="<?= $data['username'] ?>">
<form>

The function that retrieves data is just as a placeholder to make clear data comes from server and then is used to fill form values.

Now let’s see how data integrity can be put in place. It is usually done with an a two-way (reversible) encryption.

<?php
function obfuscate_postid($id) {
  return wp_create_nonce('pre-md5').md5($id.AUTH_SALT).wp_create_nonce('post-md5');
}

$data = get_my_form_data();    
$check = obfuscate_postid($data['postid']);
?>
<form method="post">
    <input type="hidden" name="postid" value="<?= $data['postid'] ?>">
    <input type="text" name="vote" value="<?= $data['vote'] ?>">
    <input type="text" name="username" value="<?= $data['username'] ?>">
    <input type="hidden" name="__ch" value="<?= $check ?>">
<form>

This way in the server-side processing you can check that

$valid = obfuscate_postid($_POST['postid']) === $_POST['__ch'];

If an user change the post id in the form without changing the check string, $valid above is false and you can stop processing the data.

I’ve used a pretty simple 2 way obfuscation, and thanks to fact that nonces are not fixed in time, this is a pretty strong way to secure your data.

I also used nonces to make the answer a bit more WordPress related 😉

It would be a very strong system if nonces would be usable only once, but it is a post voting system, not an online-banking application. And if you want you can also change nonces TTL.

Finally, note how I used a salt to make md5 more secure, because even if md5 is not reversible, result of md5 for sole integers can be easily found (e.g. try this using the string b706835de79a2b4e80506f582af3676a).