1

I have this point of sale interface for cashiers (private for my personal use) in php. So what you do is you select the drinks and then quantity per drink and hit a button that makes javascript in master.js send a jquery ajax request to processSale.php. The thing is that anyone can send a request to processSale.php. And if I put a 'key' in that javascript function, people can see it because they can just look up the file. How do I make these requests to my php files private so only I can send requests to them?

Techmo
  • 83
  • 1
  • 1
  • 12

3 Answers3

2

Establishing a cookie session between the client (master.js) and server (processSale.php) will ensure that no one can forge a request to your server, unless a highly advanced, roundabout method is out there.

https://www.w3schools.com/php/func_http_setcookie.asp This can get you started with using cookie sessions in PHP

Bill Baits
  • 82
  • 9
1

How do I make these requests to my php files private so only I can send requests to them?

Well, you can't really, short of having some sort of login or way to validate the request.

And if I put a 'key' in that javascript function, people can see it because they can just look up the file.

The trick is that the key should be different for every user, every session. That way, only authorized users can take actions, and they can only take those actions on their own behalf on data that they should have access to.

The way I usually handle this...

When a user logs in and I've authenticated and authorized them, I pass them back a key generated only for their session. I do this over HTTPS, so that hopefully only the client receiving it sees what this key is.

The client then makes API calls and signs them. That is, the client figures out what's in the request data, like:

POST /processSale.php

{
  "items": [
    {"sku": "012345", "name": "Root Beer"}
  ]
}

It then figures out the relevant portion of the request data, hashes them along with the relevant request data (see HMAC), and sticks the hash in with the request.

One thing to note here is that the key never left the client. That is, we used one-way hashes, so that future requests don't actually have to contain the key. The server knows what's going on, so it can re-hash to validate that a client knowing the key had to have made the request. The server also knows that nobody fiddled with the request data, because if they did, the hashes wouldn't agree.

This is a pretty broad topic, so I'm going to leave it there for now. I recommended reading up on this signed API request method, and HMAC to ensure the signing is done well.

Brad
  • 159,648
  • 54
  • 349
  • 530
0

You need to physically secure the location where you use your scripts, so no one could look up your secrets. E.g. by using so called Kiosk mode, available in Chrome and other browsers.

Other than that it's advisable to use temporary secrets on per request basis, they would work just like the usual CSRF tokens, but limited in time. Give a random secret string stored somewhere, you can create such token with:

$timeInFuture = time() + 600; // 10 minutes
$signedTime = sprintf('%s-%s', $timeInFuture, hash_hmac('sha256', $timeInFuture, SERVER_SECRET));

Use it by adding as a hidden field:

<input type="hidden" name="token" value="<?=$signedTime?>" />

And then verify:

do {
    if (empty($_POST['token'])) {
        // token missing
        break;
    }

    list ($timeValidUntil, $hmac) = explode('-', $_POST['token']);

    if ($timeValidUntil < time()) {
        // past the validity time
        break;
    }

    if (!hash_equals(hash_hmac('sha256', $timeValidUntil, SERVER_SECRET), $hmac)) {
        // signature invalid
        break;
    }

    // Token valid, now can secure a purchase

} while (false);

Unless you physically secure your location, it is still possible to send forged requests no matter if you use these tokens or align with cookies. Secure point of sale (POS) environment is impossible without physical security.

sanmai
  • 29,083
  • 12
  • 64
  • 76