Form Action Value?

All of the HTML Forms on my website are submitted back to themselves and processed using PHP.

Is it okay to leave the Form Action blank like below…


	<form id="login" action="" method="post">

I have read that some people consider that insecure, but most of what I have read says it is okay.

What do you think?

Sincerely,

Debbie

DD,

I’d never seen that before. If I want to return the form to the same script for processing (my usual practice), I use <?=$_SERVER[‘PHP_SELF’]?>. At least I know that the server can’t confuse my intentions with the “bit bucket.”

Regards,

DK

You should always know where your forms are being sent from!
If you are security aware then you check the forms submitted origin as its very easy to set up a spoof form on a different server and hammer your scripts at will.

Adding on to what Spike said about form security, to verify the form’s origin, I typically include a token as a hidden input and compare it to a session variable.

Some examples:

http://phpsecurity.org/code/ch02-5

http://johnsquibb.com/articles/PHP-security-tips/tokens

http://www.phpfreaks.com/tutorial/php-security (scroll down to section #8)

…but don’t use md5() for hashing, use hash() instead.

Why not use md5? Is it slow or something?

Mr. Security is advising me to use $_SERVER[‘PHP_SELF’]… :eek:

Try Googling…

$_server ‘php_self’ security risk

Sorry, but that is bad advice…

Debbie

No it isn’t. Just because people don’t use it correctly doesn’t mean it is bad advice or unsafe. You need to validate ALL input you spit back out. Just because several don’t validate the value PHP_SELF contains, doesn’t mean PHP_SELF is insecure. You can validate it, use htmlentities, urlencode, whatever to protect it from an XSS very easily.

It isn’t up to PHP to do that for you, people need to take responsibility for the misunderstanding of these attacks instead of passing the blame around.

It’s reversible/crackable, thus not a secure method for providing hashes.

Looks like this is going to be a long, PITA topic… :rolleyes:

Okay, so since you guys shot down my “This should be a quick thread”…

While I am reading the links, can someone explain a little more why leaving action blank is bad?? (Most sources I have read say it is safe for self-posting forms, and MUCH safer than using PHP_SELF…)

Sincerely,

Debbie

Sorry, I don’t want to confuse you, I don’t think leaving it blank is terrible or a sin by any means, I just wanted to clear up your confusion with using PHP_SELF. PHP_SELF by itself is not inherently evil, but it is an INPUT, so you need to treat it as such and validate/sanitize it before using it.

blank seems to suit your needs, but keep in mind (I think), it will send all of the URL arguments back to the current page too. So I could manipulate the URL, mess with any variables, submit the form, and if you aren’t validating/sanitizing them, you could be wide open to an attack on a page you thought wasn’t susceptible.

Love learning from you guys!

Just frustrated because I can never get v2.0 done, because either I or someone else finds some fault in something I’ve done.

When does it end?!

I thought this would be a super quick thread. (“Looks good, Debbie”)

I see this topic draining yet another week out of my life…


Back on topic…

Some things you should know…

  • Every PHP script I have follows this format: PHP at top, HTML below

  • All of my Forms are submitted back to themselves.

  • I sanitize all Form Data using PHP before processing

  • I think I use pretty rigorous Data Validation often checking Form Data against my Database

  • I only use Prepared Statements

  • All Forms will be loaded and submitted over HTTPS

  • I will likely make 100% of my website HTTPS



		<form id="createAccount" action="" method="post">

If anyone sees this as insecure, please explain why!

And, better, offer a more secure alternative.

Based on my research, what I have above is fine.


As far as $_SERVER[‘PHP_SELF’], you are correct that it is not inherently bad.

But, of course, it would just echo whatever was sent, so if someone appended nefarious strings to the end of the Form, then I believe that would be carried over back to my self-submitted Form.


As far as the links, I am slightly familiar with their existence, but am wondering if that isn’t all tangential based on what I have described above?

I have wanted to incorporate the Form Token thingy, but that is just more work that adds to my never ending SCOPE CREEP…

And at some point I either have to decide to stay in “Perpetual Development Mode” or “Get On with It!!” and go live.

(It’s a fine balance, but I feel I have already done soooo many good, security-based things that I have to question if I need more for v2.0?!) :-/

Sincerely,

Debbie

Here’s an interesting write up in 2009:
http://stackoverflow.com/questions/1131781/is-it-a-good-practice-to-use-an-empty-url-for-a-html-forms-action-attribute-a

It actually recommends removing the action attribute all together. Why have an empty one, just remove it! :slight_smile:

Another thing to note: HTML5 doesn’t support action=“”, it asks that you remove the attribute.
http://stackoverflow.com/questions/1131781/is-it-a-good-practice-to-use-an-empty-url-for-a-html-forms-action-attribute-a/9678030#9678030

I already read both of those earlier before you posted here.

The first one mentions possible “iframe clickjacking” attacks if you have value=‘’

Neither of those threads left me feeling there was a definitive answer.

It has just been my stance based on reading a lot over the years that what I have is secure.

But I certainly would welcome someone who is a security and web guru to give a more definitive “Yay” or “Nay”.


Not to get too far into the grass, but how important is it to have that Form Token thingy that ForceFlow’s links talk about?

Sounds like a good idea, but I’m not sure how common of an attack vector that really is?!

The only way I see it working is if some “friend” sent you an email saying, “Go check out this website. Just click on the link and use these credentials to log in the web form…”

Other than that, how else would someone hijack your form - especially over HTTPS?!

Sincerely,

Debbie

Oh. I thought the whole point of having a form token was to prevent CSRF, not to figure out what the actual contents of the hash contains.

You should subscribe to Troy Hunt’s RSS Feed.

And here are some of my favorite articles of his:
Your login form posts to HTTPS, but you blew it when you loaded it over HTTP
Cross-Site Request Forgery (token recommendation by ForceFlow solves this)
5 ways to tackle insufficient HTTPS
Understanding the risk of mixed content warnings
Understanding XSS

Another tidbit (and someone correct me if I’m wrong), but for a CSRF to pass your authentication, you have to be storing the authentication of your user in a Cookie. If the authentication is stored in Session (and not a physical cookie), then the malicious site won’t be authenticated.

When you read Troy’s article, you will see that in the image under “What made this possible?”, there is a “Cookie:” that has the Username (and likely some sort of authentication property). If you only used Session for the authentication, as soon as the person leaves the site, that Session is useless to anyone else.

As far as how hard is it to implement? Not that hard.

[list=1][*]Generate your token on first visit to your site:

if (!isset($_SESSION['token'])) $_SESSION['token'] = crypt(uniqid());

[*]For each form, place a hidden field that contains your token

<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>" />

[*]On each form submission, validate the token

if ($_REQUEST['token'] !== $_SESSION['token']) die('Sorry, you are not allowed access.');

[*]Breathe a sigh of relief, you just prevented a CRSF attack
[/list]

It is, but if you can reverse the hash, you can probably figure out how it’s being generated, and thus, forge one.