3

I have fileA.php on SERVER_A and fileB.php on SERVER_B

fileB.php makes a curl request to fileA.php for it's contents

How can fileA.php determine that the request is coming specifically from fileB.php?

--

I was thinking about sending the $_SERVER['SCRIPT_NAME'] in fileB.php to fileA.php but since someone can go into fileB.php or any file in general and just do $_SERVER['SCRIPT_NAME'] = 'fileB.php'; it's not really that secure.

So how can I determine, for security reasons, that the request is coming from a specific file on a different server?

Mickey
  • 2,285
  • 6
  • 26
  • 37
  • 2
    Do you absolutely need this to be 100% secure? Because if so, I recommend you find another way of doing this. – Sasha Chedygov Apr 15 '10 at 03:09
  • Does fileA.php need to be publically accessible? If your question is how to make fileA.php accessible *only* to fileB.php, then you can look into using HTTP authentication to add password protection (password can then be specified as a parameter to curl in fileB.php). – Todd Owen Jun 12 '10 at 08:56

7 Answers7

4

You can't, reliably. You can try setting a HTTP header and verifying that on the other side; it's not fool-proof, but it's better than most.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
3

Why not set up a secret token, and verify it on the receiving end?

// fileB.php

$url = "http://example.com/fileA.php"
     . "?from=fileB"
     . "&token=" . sha1('fileB' . 'myaw3som3_salt!')
;
// then make the cURL request.


// fileA.php
if (sha1($_GET['from'] . 'myaw3som3_salt!') != $_GET['token']) {
    die();
}

This is a simplistic example here, but you get the idea.

nickf
  • 537,072
  • 198
  • 649
  • 721
  • I use this technique to store passwords in a database, sha1 the password with a key but if the "token" in this case is viewable in the url and that's all i checked for or all i was able to check for it'd be even easier for them to spoof – Mickey Apr 21 '10 at 07:59
  • @John: perhaps include `$_SERVER['HTTP_REFERER']` into the string before hashing? – nickf Apr 21 '10 at 14:56
2

Impossible, because of your statement:

"since someone can go into fileB.php"
zaf
  • 22,776
  • 12
  • 65
  • 95
0

Once you request outside your server you have really no control. If fileA on the other server has the possibility of man-in-the-middling fileB, you need to rethink your security model. What's the specific situation?

Xorlev
  • 8,561
  • 3
  • 34
  • 36
  • well if i can't secure it i won't code it. this specific situation is me just trying to come up with a way to run code on a clients server without it actual being there and without them being able to see it. I'm trying to code something like fileB.php {eval(file_get_contents(fileA.php));} and fileA.php {ftp fileB.php - if md5 of fileB.php is of it's orginal and request coming from fileB.php and a couple of other things - give it the php code from SERVER_A to eval, otherwise give it something to eval like die()} just trying to see what i can make php do =/ – Mickey Feb 21 '10 at 05:57
  • i mean curl, not file_get_contents, sorry. – Mickey Feb 21 '10 at 05:58
  • 2
    This honestly sounds doomed to failure. There isn't a good way to do this. You can provide a script which has been "encrypted" by something like ioncube or zend encoder and force them to run those PHP modules, then only provide the encrypted PHP, but these have been proven to be less than secure. – Xorlev Feb 21 '10 at 08:03
0

One way would be to check the

$_SERVER['HTTP_REFERER']

variable in PHP, but it is the browser's decision to populate this so it can't be fully trusted.

Rouan van Dalen
  • 748
  • 4
  • 14
0

Little can be done if a 3rd party has access to fileB.php. REFERER gives you no protection. REMOTE_ADDR is not as trivial to spoof, that might give you some assurance that the request is legit.

BojanG
  • 1,872
  • 1
  • 15
  • 23
0

I think nickf was spot on, but just to expand on his answer a little bit, here's what I would do:

  • fileB.php on Server1 requests fileC.php on Server2
  • fileC.php on Server2 returns a randomly-generated salt, stores it in a file or database with a timestamp
  • fileB.php on Server1 requests fileA.php on Server2, and sends as its request body a preconfigured key, hashed, appended with the random salt and hashed again (e.g. sha1(sha1('mypassword') . $salt))
  • fileA.php checks if a salt has been generated in the last 60 seconds, if not returns an error
  • fileA.php performs the same hash with its last random salt and preconfigured key - sha1(sha1('mypassword') . $salt) again, which is compared with the request body as sent by fileB.php. If they match, fileA.php grants access to fileB.php.
  • fileA.php deletes the last salt that was generated.
zbateson
  • 1,044
  • 10
  • 11
  • Also if you're worried about man-in-the-middle, use HTTPS... this is probably adequate and reasonable protection – zbateson Jun 12 '10 at 01:59