Stopping a piece of PHP from being accessed unless it is being called by something...

  • Thread starter Thread starter Bes
  • Start date Start date
I don't follow :confused:

He presumably has several forms on different pages, each of which do something for the user using the script. Whether the form sends the browser back to the same page, which then includes the script, or just sends the browser directly to the script is irrelevant and has no bearing on how easy it is to secure. In both cases the form's recipient will need to check some post data to authenticate the request.

If he wants to secure it while keeping it public, he's going to have to use some kind of token mechanism like Rob and I suggested above.

The nature of the pages/site structure will dictate exactly where the form sends the browser to, be it the current page or the script itself.
 
It's simple.

page.php is the dangerous page.

It's far easier to just keep page.php out of public folders, and use php to include() it if it's needed for other areas.

If page.php is in the public folder, anyone can (pedantically) access it, page.php then has to determine who is allowed to proceed or not. Why bother with the extra effort of nonces? If the page isn't include()d by a page elsewhere, it is impossible to run it.

It's like having every individual soldiers carry armor plating, when it would be much easier to just have them all board an APC.

Think of what a front controller does.. everything goes through it, and it decides who is allowed to see what. This is exactly what this is.
 
There are a few forms (Only about 3 or 4 at the most) that access page.php.

They do this by including it in image tags and sending a number of parameters within the image tag (i.e. <img src="page.php?a=1&b=44&c=5">) etc. The parameters are built up as the user wishes using a Javascript- based form, so all the values are sanity checked, etc before being passed on. The PHP then uses magickWand to manipulate an image as per the parameters. The php code then returns the image in the image tags above.

I get what you are saying Dj_Jestar, so if I just have the MagickWand lines inside a file outside the reach of the public, then make PHP call it, I should be safe, as no one can run the code?

The only danger I still see is that someone can then just type into the address bar the URL of the PHP page, insert some massive values, or launch a DOS attack, and bring down my app... I can see how a session can prevent this, but not your method.

Thanks
 
Last edited:
well you can't stop page.php - you're accessing it using img tags. this is basic html. the browser needs to see the file. :)

instead sanitise the input within page.php
 
It's simple.

page.php is the dangerous page.

It's far easier to just keep page.php out of public folders, and use php to include() it if it's needed for other areas.

If page.php is in the public folder, anyone can (pedantically) access it, page.php then has to determine who is allowed to proceed or not. Why bother with the extra effort of nonces? If the page isn't include()d by a page elsewhere, it is impossible to run it.

It's like having every individual soldiers carry armor plating, when it would be much easier to just have them all board an APC.

Think of what a front controller does.. everything goes through it, and it decides who is allowed to see what. This is exactly what this is.

I understand exactly what you're saying but it doesn't work.

page.php is used as an image source on the site in question, so the browser must be able to make requests to it as necessary, and any authentication process must be transparent.

What you're suggesting is that page.php is placed outside the docroot and is included by some other file. However, this intermediate file must then also be accessible in order for the browser to request the resource provided by page.php, so ultimately, the situation hasn't changed at all. Of course, the user can't directly access page.php, but that doesn't make a blind bit of difference as it's still being run, which is what Bes wants to prevent.

To break it down, the page.php resource obviously has to be accessible for displaying images on the site, but what we want to prevent is people accessing the resource for other reasons. Thus, we need to authenticate the origin of the request, and the only way of doing this transparently is by using nonces.

I also don't really understand your APC analogy; what I was suggesting was that page.php along contained nonce authentication code, so I don't see how this is analogous to lots of soldiers having armour :confused:
 
Thanks for the great discussion guys, will go with the suggestion further up (nonces?).
I have to sanitise the input at the Javascript level so the user can see exactly what they are submitting (This is done by defaulting to what I think the user wants if they go outside the bounds of the input for fields where numerical stuff is needed, plus I am blocking non 0-9 characters, etc). I am also going to flood- control anything that calls the dangerous php file to prevent more than 1 request every 2 seconds or so.

Does this method mean I don't have to do any sanitising on my PHP, as the only way the user can hit the page is by submitting the correct token? or is it possible for a user to spoof the token once inside the session, and send my dangerous php file massive values?
 
Thanks for the great discussion guys, will go with the suggestion further up (nonces?).
I have to sanitise the input at the Javascript level so the user can see exactly what they are submitting (This is done by defaulting to what I think the user wants if they go outside the bounds of the input for fields where numerical stuff is needed, plus I am blocking non 0-9 characters, etc). I am also going to flood- control anything that calls the dangerous php file to prevent more than 1 request every 2 seconds or so.

Does this method mean I don't have to do any sanitising on my PHP, as the only way the user can hit the page is by submitting the correct token? or is it possible for a user to spoof the token once inside the session, and send my dangerous php file massive values?

Erm don't just sanitise your input at the client side (because you can just disable js/breakpoint on it and change values). You should be doing it at the server side as well.

In theory you could spoof the token.. depends how your generating it.
 
Does this method mean I don't have to do any sanitising on my PHP

Whoa, absolutely not. Any critical validation/authentication should always, always be done server-side. Remember, JavaScript is a client-side scripting language and runs within the browser.

For this reason it's possible for an attacker to manipulate JavaScript scripts that your site uses (or just disable them altogether – in fact I personally have JS disabled by default for all pages unless I whitelist them myself).

There's nothing wrong with using JavaScript for validation, and it can be very useful to the user as it can be used to inform them of problems on the fly without them having to load a new page. However, always make sure that there's a server-side (e.g. PHP) check done after that, just to double check.

For a good demonstration of nonces, see Rob's PHP security guide:
http://php.robm.me.uk/#toc-CSRF
 
In theory you could spoof the token.. depends how your generating it.

I suppose you could get the server to generate some tokens and then not actually use them in the requests they were intended for and just use them all later or something, but I don't see what use that would be.
 
Ok thanks

Unfortunately, due to the nature of my site, Ajax is pretty important to get everything looking nice and intuitive, but I am putting everything the user needs in divs, so should javascript be disabled, all the stuff should still load at the bottom of the screen, and most of it will work! (The site will be slightly crippled without it though).
 
I understand exactly what you're saying but it doesn't work.

page.php is used as an image source on the site in question, so the browser must be able to make requests to it as necessary, and any authentication process must be transparent.

What you're suggesting is that page.php is placed outside the docroot and is included by some other file. However, this intermediate file must then also be accessible in order for the browser to request the resource provided by page.php, so ultimately, the situation hasn't changed at all. Of course, the user can't directly access page.php, but that doesn't make a blind bit of difference as it's still being run, which is what Bes wants to prevent.

To break it down, the page.php resource obviously has to be accessible for displaying images on the site, but what we want to prevent is people accessing the resource for other reasons. Thus, we need to authenticate the origin of the request, and the only way of doing this transparently is by using nonces.

I also don't really understand your APC analogy; what I was suggesting was that page.php along contained nonce authentication code, so I don't see how this is analogous to lots of soldiers having armour :confused:
Soldiers = pages. APC = Controller or Webserver.

I didn't realise the page would be used as an image source. Seems daft to need this security on the image source, instead of needing it on the page requiring the image in the first place.
 
Soldiers = pages. APC = Controller or Webserver.

I didn't realise the page would be used as an image source. Seems daft to need this security on the image source, instead of needing it on the page requiring the image in the first place.

But the point is that someone could just call the image source regardless, and as it takes CPU time to process images (And it can be a lot if loads of parameters are passed), could quite easily be used as the basis of a DOS attack. I just want to lock it down so only valid requests can be processed.
 
I didn't realise the page would be used as an image source. Seems daft to need this security on the image source, instead of needing it on the page requiring the image in the first place.

The whole point is that the page that uses the resource is public, so there can't be any security on it.
 
I don't understand. Tell me what putting security on the page linking to the image (as opposed to the image resource itself) would actually achieve, other than making it non-public (which is undesirable).

page1.php – public; anyone must be able to view; no authentication
Code:
<!-- some stuff -->
<img src="image.php" />
<!-- some stuff -->

page2.php – public; anyone must be able to view; no authentication
Code:
<!-- some stuff -->
<img src="image.php" />
<!-- some stuff -->

image.php – only allow requests from page1.php and page2.php
Code:
<?php

// Expensive/dangerous operation:
output_image();

?>
 
Last edited:
a) what I posted is a buttload easier than messing with nonces.
b) Separated behaviour - i.e. good practice.
c) The security emphasis is now on including a script *only* when security has passed, not including it then worrying about security. "Defense In Depth" encourages practices like this.
d) You can't ask for a password with an image resource like that above.
 
Yeah but the crucial problem with putting security on all pages, including the image, at controller-/server-level (is this what you're saying?) is that they end up being non-public, which makes the solution unworkable. If they don't need to be public then a password is great; that was my first suggestion.

The whole point is that everything must be public and accessible to anyone.

edit: can you post a full example (image resource source, source of pages linking to image resource, any server/controller authentication routines), as every possible solution I've managed to infer from your posts either doesn't work or doesn't do what Bes wants.
 
Last edited:
Back
Top Bottom