Page 1 of 2

form action="$_SERVER['PHP_SELF']"

Posted: Sat May 13, 2006 10:46 am
by seodevhead
Hey guys... I have heard various articles over the past couple months state that you shouldn't rely on $_SERVER type variables as they are unpredictable, etc.

But is it safe to do the following for a form on my website?

Code: Select all

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
Or does this leave me open to a security hole? Can a user impart his will on this PHP_SELF variable I am echoing? Thanks for any advice and suggestions. Take care.

Posted: Sat May 13, 2006 1:50 pm
by Burrito
two notes:

1) There are some $_SERVER variables that you can NOT rely on, but even the ones you can't, I've yet to see return what you're not expecting.
2) I've never understood why people use SELF in a form action. There's no reason for it at all. If you want the form to post to itself, just leave the action attribute out of the tag.

Posted: Sat May 13, 2006 4:54 pm
by Christopher
I think the problem with PHP_SELF is that it is not present on all servers. I tend to use SCRIPT_NAME and SERVER_NAME. Here is some info I found a while back at phpguru:

Everything from $_GET, $_POST, $_COOKIE and $_REQUEST should not be trusted.

From $_SERVER:
* Anything prefixed with HTTP_
* PHP_SELF
* PATH_TRANSLATED
* PATH_INFO
* argv
* PHP_AUTH_USER
* PHP_AUTH_PW
* REMOTE_HOST (though not always, and this is much harder to inject into as it's usually the result of a DNS lookup performed by the web server)

From $_FILES:
* name
* type

From $_ENV when running in CGI mode, contains everything from $_SERVER, so the same keys apply.

Posted: Sat May 13, 2006 6:13 pm
by timvw
Here's an interesting article on $_SERVER['PHP_SELF']: XSS Woes.

Anyway, people want to use the variable because it allows them to keep the users at the same URL they where coming from. Using the constant '#' as action does just the same and doesn't have the security issues...

Posted: Sun May 14, 2006 10:21 am
by Maugrim_The_Reaper
There are other reasons to use PHP_SELF outside just forms...
You can clean it before use (usually only for same file references) using:

Code: Select all

$phpself = basename(__FILE__);
$_SERVER['PHP_SELF'] = substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], $phpself)) . $phpself;
As a secondary redundant measure you can also htmlentities() the variable for actual use.

Posted: Wed May 17, 2006 11:20 am
by techleet
arborint wrote:Everything from $_GET, $_POST, $_COOKIE and $_REQUEST should not be trusted.

If $_GET, $_POST cannot be trusted, how do you handle forms...?

Posted: Wed May 17, 2006 11:21 am
by JayBird
techleet wrote:
arborint wrote:Everything from $_GET, $_POST, $_COOKIE and $_REQUEST should not be trusted.

If $_GET, $_POST cannot be trusted, how do you handle forms...?
Basically he means you shoul dnever trust user input and all data should be sanitized. Just becuase you are expecting certain values doesn't mean the user will enter them correctly

Posted: Wed May 17, 2006 12:17 pm
by Roja
techleet wrote:If $_GET, $_POST cannot be trusted, how do you handle forms...?
Think like a bank..

If you can't trust people to give you the right amount of money, how do you handle the money?

Count it!

When you expect a user to give you a (for example) number from 1-10, make sure that the only thing you accept, by filtering, and cleaning, and similar actions.

Posted: Wed May 17, 2006 12:32 pm
by techleet
Basically he means you shoul dnever trust user input and all data should be sanitized. Just becuase you are expecting certain values doesn't mean the user will enter them correctly
Ohhhh... of course! You guys scared me for a second there!! :lol:

Posted: Wed May 17, 2006 2:55 pm
by andym01480
Facsinating stuff. Read all the links you guys posted.

Follow up question though...

Assuming I have changed

Code: Select all

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
to

Code: Select all

<form action="#" method="post">
as timvw suggests.

that outputs as is.

Couldn't a naughty peep just change the # for the url followed by the bad stuff and then press submit?

Or am i missing the entire point?

The real question, I guess, is how does the attack work?

Posted: Wed May 17, 2006 3:02 pm
by Maugrim_The_Reaper
Typically the simplest attack would be getting someone to visit the doctored URL containing the exploit. Maybe a forum link, or a PM, or something else. Not everyone checks the full url in their browser status bar before visiting a link.

Posted: Wed May 17, 2006 3:06 pm
by andym01480
I think you are saying that the attack happens by a third party doing something to PHP_SELF so that when a poor unsuspecting user opens the page with the form the form submit executes the extra code? :oops:

If so then # stops that because the 3rd party can't change the unused PHP_SELF. :wink:

How do they doctor the PHP_SELF - is that something that can only happen on a shared server?

As an aside the status bar can say whatever you want it to say with

Code: Select all

<SCRIPT>
self.defaultStatus ="Whatever I want to say in the status bar"
</SCRIPT>

Posted: Wed May 17, 2006 3:13 pm
by Maugrim_The_Reaper
http://blog.phpdoc.info/archives/13-XSS-Woes.html

It's possible to alter the variable using mod_rewrite on Apache. Just edit a valid URL in a specific way to inject an external reference to a javascript file to execute in the client. The js can do almost anything js is capable of - including stealing the user's cookie details. Now if the user is logged into the affected site, and one gets their cookie data, they have enough information to potentially mimic the user by copying their PHP session id. If you can mimic the user - you can access the application and do "bad things" from their account. Lots more to it, but there one possible usage...

Posted: Wed May 17, 2006 3:29 pm
by andym01480
Okay. Quickly looked at mod_rewrite in google and also at the article you linked to Maugrim.

If I'm not using mod_rewrite in .htaccess files, is

Code: Select all

$_SERVER[PHP_SELF]
safe from attack?

Re: form action="$_SERVER['PHP_SELF']"

Posted: Wed May 17, 2006 4:16 pm
by mudvein
seodevhead wrote:Hey guys... I have heard various articles over the past couple months state that you shouldn't rely on $_SERVER type variables as they are unpredictable, etc.

But is it safe to do the following for a form on my website?

Code: Select all

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
Or does this leave me open to a security hole? Can a user impart his will on this PHP_SELF variable I am echoing? Thanks for any advice and suggestions. Take care.
in all reality, if you are posting to the page you are showing, you don't even NEED to put an action statement in there...
so this

Code: Select all

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
would just become this :

Code: Select all

<form method="post">

after trying it out, you will see you get the exact same result...