I’m running a cronjob which needs to write data to a cache. I wanted to put this cronjob in my private folder, however, even after CHMODding the cache folder in the private folder, it’s not getting writing rights. This seems to be somekind of plesk feature.
So, now I’ve placed the cronjob in the public folder. However, I need to make sure that only the server can execute the script. What about the following at the top of the cronjob?
if ($_SERVER['SERVER_ADDR'] != $_SERVER['REMOTE_ADDR']) die();
This seems to work. Is it not exploitable however, eg. can a user manipulate his remote_addr to my server’s? Or is there a better way to check this?
Another issue I have is that the above code is returning 2 warnings, even though it does seem to work:
PHP Notice: Undefined index: SERVER_ADDR in ... on line 2 PHP Notice: Undefined index: REMOTE_ADDR in ... on line 2
Any idea what’s the cause of that?
Execute the script via the console, not the web server.
The cron could look like this:
Then the file could do this:
That will guarantee it’s only run by the server.
Edit in response to comments
You can’t get to a public folder inside a private folder, in general, and if you can’t add new directories outside the web root, your cache dir will have to be protected another way.
I’m going to assume all your files are in the web root, ie:
/home/site/publichtml. Replace that with whatever your directory is.Create a new directory
/home/site/publichtml/.cache. Add the following as a .htaccess file:Now your scripts should be able to access the folder from the file system, but it’s inaccessible via the web server.
If you can set up a cron job on the server (via the web admin or another way, it sounds like you can) do it as above, ie: Use
php -f /home/site/publichtml/cron.phpas the command, and include the check for the array key.Alternatively, you can check like this:
$_SERVER['argc']is only set when the script is executed from the command line.If you can keep the cron script out of the web root, good. If not, that should be secure.
Finally, to get rid of the E_NOTICES, add this to the top of the cron.php:
or