2

Help! I'm writing some code to update a mySQL database using similar to the code below:-

$.post('http://myURL.com/vote.php?personID=' + personID + '&eventID=123');

The vote.php code takes the querystring values and inserts a record into a database with those values in it.

This kind of code is working fine, but I've realised the problem is that people could just type something like:

http://myURL.com/vote.php?personID=5&eventID=123

into their address bar and essentially spam the app...

Is there a straightforward way I can ensure this doesn't happen? I'm reasonably new to these technologies so not aware of how everything works or fits together, but I'm learning fast so any pointers would be super useful.

1
  • I guess that the best should be to encrypt always the data, and decrypted when you received it. Commented Jun 4, 2012 at 12:36

3 Answers 3

3

It is not a good idea to use GET parameters for data that goes to a database. Generally, you want to use POST parameters which are not visible in the URL. So instead of :

$.post('http://myURL.com/vote.php?personID=' + personID + '&eventID=123');

You would do it like this :

$.post('http://myURL.com/vote.php', { "personID" : personID, "eventID" : 123 });

And in your PHP script, you would access your data with the $_POST array like this :

$personID = $_POST['personID'];
$eventID = $_POST['eventID'];

However, don't forget to properly filter input before saving to the database to prevent bad things like SQL Injection.

This is not a silver bullet : spam will still be possible because any HTTP client will be able to send a post request to your site. Another thing you can look at is Security Tokens to make it even less vulnerable to spam. Or implement a system that limits the number of request/minute/user... but I'm getting too far from the original question.

Sign up to request clarification or add additional context in comments.

Comments

0

Correct syntax of $.post is

$.post(url,data_to_send,callback_function)

By using this method your user will never be able to damage your site.Use like

$.post('http://myURL.com/vote.php',{"personID":personID,"eventID":123);

4 Comments

This works great and looks much better, thanks. The main issue I have however is to figure a way that somebody doesn't build a querystring and type it into the address bar.
Would using get rather than post be a better option for this? Apologies if my questions seem silly, as I said I'm still picking this stuff up.
don't forget to click on check mark at the left side of answer
No don't use $.get for this as it is not safe
0

Whether you're using POST or GET, you could always consider signing important fields in your page by using hash_hmac. This prevents people from changing its value undetected by adding a signature that no one else can guess.

This also makes CSRF more difficult, though not impossible due to fixation techniques. It's just yet another technique that can be put in place to make it more difficult for "fiddlers".

The following function adds a salt and signature to a given person id to form a secured string.

define('MY_SECRET', 'an unguessable piece of random text');

function getSecurePersonId($personId)
{
    $rnd = uniqid("$personId-", true);
    $sig = hash_hmac('sha1', $rnd, MY_SECRET);

    return "$rnd-$sig";
}

You would pass the output of getSecuredPersonId() to JavaScript to pass as data in the $.post() or $.get(); posting would be recommended btw.

When the form is submitted your person id would end up in either $_GET['personID'] or $_POST['personID'] depending on the request method. To validate the given value, you run it through this function:

function validateSecurePersonId($securePersonId)
{
    if (3 != count($parts = explode('-', $securePersonId))) {
        return false;
    }
    // reconstruct the signed part
    $rnd = "{$parts[0]}-{$parts[1]}";
    // calculate signature
    $sig = hash_hmac('sha1', $rnd, MY_SECRET);

    // and verify against given signature
    return $sig === $parts[2] ? $parts[0] : false;
}

If the value is properly signed, it will return the original person id that you started out with. In case of failure it would return false.

Small test:

$securePersonId = getSecurePersonId(123);
var_dump($securePersonId);

if (false === validateSecurePersonId($securePersonId)) {
    // someone messed with the data
} else {
    // all okay
}

1 Comment

Please provide more details about how to use this piece of code and how does it help to solve the problem. As it is now, it provides absolutely no value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.