[How-To] PHP Security

Associate
Joined
23 Oct 2002
Posts
1,525
Location
That London, née Brighton
if i may be so bold...

best way i've found for handling the old '?page=blah' issue, is to store pages in database. so ?page=3 will go off and pull the record id=3 from a 'pages' table in the database to get the filename (or maybe the content directly). naturally some integer checking+casting on the $page input too.
 

Ben

Ben

Associate
Joined
18 Oct 2002
Posts
2,328
Location
Kent
Tetsujin said:
if i may be so bold...

best way i've found for handling the old '?page=blah' issue, is to store pages in database. so ?page=3 will go off and pull the record id=3 from a 'pages' table in the database to get the filename (or maybe the content directly). naturally some integer checking+casting on the $page input too.

Problem is most people who want to use the ?page=blah are relatively new to coding in PHP and usually aren't aware of the possible exploits when using such a simple script.

Disclaimer: Note the use of "most" and "usually".
 
Soldato
OP
Joined
26 Dec 2003
Posts
16,522
Location
London
Tetsujin said:
if i may be so bold...

best way i've found for handling the old '?page=blah' issue, is to store pages in database. so ?page=3 will go off and pull the record id=3 from a 'pages' table in the database to get the filename (or maybe the content directly). naturally some integer checking+casting on the $page input too.


But that still doesn't tackle the old search engine chesnut, which is where some mod_rewrite craftiness comes in handy. Even if you have to use the query string, then an ID isn't the best choice - what's it showing? The ID of what? It'd be much better to put a snippet of the title in the variable so there's at least something descriptive in the URL.
 
Soldato
Joined
12 Apr 2004
Posts
11,788
Location
Somewhere
Tetsujin said:
if i may be so bold...

best way i've found for handling the old '?page=blah' issue, is to store pages in database. so ?page=3 will go off and pull the record id=3 from a 'pages' table in the database to get the filename (or maybe the content directly). naturally some integer checking+casting on the $page input too.
I find it easier just to define an associative array of all the pages I want to be 'includable', so if I go to index.php?page=blah then it looks up the array element with the key 'blah' and includes the correct file :)
 

Ben

Ben

Associate
Joined
18 Oct 2002
Posts
2,328
Location
Kent
Inquisitor said:
I find it easier just to define an associative array of all the pages I want to be 'includable', so if I go to index.php?page=blah then it looks up the array element with the key 'blah' and includes the correct file :)

I think the main question would be, why use it like that anyway? You have to keep the file up to date with each file you want to use as a parameter.
 

Ben

Ben

Associate
Joined
18 Oct 2002
Posts
2,328
Location
Kent
Inquisitor said:
Well it means that only the pages that you want to be opened can actually be opened, so that eliminates a lot of security risks from the equation :)

hmm, how are you stopping people from going to say -
yoursite.com/pages/gallery.php directly?

this may not be revealed initally by index.php, but if someone managed to make
index.php?page=gallery error, then it'd reveal /complete/path/to/pages/gallery.php in the error.
 
Soldato
OP
Joined
26 Dec 2003
Posts
16,522
Location
London
Inquisitor said:
Well it means that only the pages that you want to be opened can actually be opened, so that eliminates a lot of security risks from the equation :)


But it's a load of work that you have no need to do, since you can eliminate all of the flaws by doing the inverse, and including the header and the footer on each of the pages, or using a templating system.
 
Soldato
Joined
2 May 2004
Posts
19,943
Ben said:
hmm, how are you stopping people from going to say -
yoursite.com/pages/gallery.php directly?

this may not be revealed initally by index.php, but if someone managed to make
index.php?page=gallery error, then it'd reveal /complete/path/to/pages/gallery.php in the error.
Thanks to robmiller whenever someone types in the wrong index.php?page= thing then it just displays the index page :)
 

Ben

Ben

Associate
Joined
18 Oct 2002
Posts
2,328
Location
Kent
Craig321 said:
Thanks to robmiller whenever someone types in the wrong index.php?page= thing then it just displays the index page :)
Yes I know that. I'm talking about accessing the included php file directly, like I showed in the 2nd half of this post. Which was my point against Inquisitor's point!
 
Soldato
Joined
12 Apr 2004
Posts
11,788
Location
Somewhere
Ben said:
hmm, how are you stopping people from going to say -
yoursite.com/pages/gallery.php directly?

this may not be revealed initally by index.php, but if someone managed to make
index.php?page=gallery error, then it'd reveal /complete/path/to/pages/gallery.php in the error.
Not if you stop it from displaying errors, which you should do anyway.
Besides, that code won't generate errors anyway. If the key does not exist in the array, it just displays a message saying the page could not be found :)
Also, I have all of the actual 'pages' in a password protected directory, so you can't just view the files themselves.
 

Ben

Ben

Associate
Joined
18 Oct 2002
Posts
2,328
Location
Kent
Inquisitor said:
Not if you stop it from displaying errors, which you should do anyway.
Besides, that code won't generate errors anyway. If the key does not exist in the array, it just displays a message saying the page could not be found :)
Also, I have all of the actual 'pages' in a password protected directory, so you can't just view the files themselves.

OK let's rephrase the question, since it doesn't seem to be clear:

how is /index.php?page=gallery any more secure than /pages/gallery.php

And with what you've said above, if people know they logic behind your code, then it wouldn't be hard to work out that:
/index.php?page=awesomepage includes /pages/awesomepage.php

besides, IMO, any included page shouldn't respond to _GET or _POST values, unless of course it's a global sanitiser!

On one of the sites I'm doing I have two included files, near the top I have
/inc/global.php included, which makes the connection to the database, and checks the _SERVER variable for login information (it's hiding behind NTLM), and creates a class based on the login information. You can go to it manually and it won't error, it just doesn't do anything that outputs anything to the browser.
The other page main.php actually outputs the content from the previous script, and if called manually (checks by seeing whether the URL is itself), it outputs the default information.

At least with that if I wanted to add a page I can just use the following as a simple template:

Code:
<?php
require('inc/global.php');

// page stuff here

require('main.php');
?>
 
Associate
Joined
23 Oct 2002
Posts
1,525
Location
That London, née Brighton
the mechanism i came up with is a single index.php which everything else is piped through. it includes a config.php which define(blah)s a constant, with a couple lines similar to

if(!defined(blah))
exit;

on every page that isn't index.php (or config.php)
 
Soldato
OP
Joined
26 Dec 2003
Posts
16,522
Location
London
You could stick this in too:

Code:
if(!preg_match('#^/index.php.*#', $_SERVER['REQUEST_URI'])) {
    die('You cannot view this page directly.');
}

but this all seems like a lot of hassle when you could just use Smarty/include a header and footer.
 
Soldato
OP
Joined
26 Dec 2003
Posts
16,522
Location
London
Well the slashes actually get added to content, so you end up seeing things like

Hello, I\'m Rob!

getting written on pages and stuff. The headache comes in when you try and deal with them, since you have to do different things to your input depending on whether magic quotes is on or not.
 
Back
Top Bottom