How to properly protect form action attribute [duplicate] - php

I am wondering if anyone can give a "best practices" response to using blank HTML form actions to post back to the current page.
There is a post asking what a blank HTML form action does here and some pages like this one suggest it is fine but I'd like to know what people think.

The best thing you can do is leave out the action attribute altogether. If you leave it out, the form will be submitted to the document's address, i.e. the same page.
It is also possible to leave it empty, and any browser implementing HTML's form submission algorithm will treat it as equivalent to the document's address, which it does mainly because that's how browsers currently work:
8. Let action be the submitter element's action.
9. If action is the empty string, let action be the document's address.
Note: This step is a willful violation of RFC 3986, which would require base URL processing here. This violation is motivated by a desire for compatibility with legacy content. [RFC3986]
This definitely works in all current browsers, but may not work as expected in some older browsers ("browsers do weird things with an empty action="" attribute"), which is why the spec strongly discourages authors from leaving it empty:
The action and formaction content attributes, if specified, must have a value that is a valid non-empty URL potentially surrounded by spaces.

Actually, the Form Submission subsection of the current HTML5 draft does not allow action="". It is against the spec.
The action and formaction content attributes, if specified, must have a value that is a valid non-empty URL potentially surrounded by spaces. (emphasis added)
The quoted section in mercator's answer is a requirement on implementations, not authors. Authors must follow the author requirements. To quote How to read this specification:
In particular, there are conformance requirements that apply to producers, for example authors and the documents they create, and there are conformance requirements that apply to consumers, for example Web browsers. They can be distinguished by what they are requiring: a requirement on a producer states what is allowed, while a requirement on a consumer states how software is to act.
The change from HTML4—which did allow an empty URL—was made because “browsers do weird things with an empty action="" attribute”. Considering the reason for the change, its probably best not to do that in HTML4 either.

Not including the action attribute opens the page up to iframe clickjacking attacks, which involve a few simple steps:
An attacker wraps your page in an iframe
The iframe URL includes a query param with the same name as a form field
When the form is submitted, the query value is inserted into the database
The user's identifying information (email, address, etc) has been compromised
References
Bypassing CSRF protections with ClickJacking and HTTP Parameter Pollution

This will validate with HTML5.
<form action="#">

IN HTML 5 action="" IS NOT SUPPORTED SO DON'T DO THIS. BAD PRACTICE.
If instead you completely negate action altogether it will submit to the same page by default, I believe this is the best practice:
<form>This will submit to the current page</form>
If you are sumbitting the form using php you may want to consider the following. read more about it here.
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Alternatively you could use # bear in mind though that this will act like an anchor and scroll to the top of the page.
<form action="#">

I think it's best to explicitly state where the form posts. If you want to be totally safe, enter the same URL the form is on in the action attribute if you want it to submit back to itself. Although mainstream browsers evaluate "" to the same page, you can't guarantee that non-mainstream browsers will.
And of course, the entire URL including GET data like Juddling points out.

Just use
?
<form action="?" method="post" enctype="multipart/form-data" name="myForm" id="myForm">
It doesn't violate HTML5 standards.

I used to do this a lot when I worked with Classic ASP. Usually I used it when server-side validation was needed of some sort for the input (before the days of AJAX). The main draw back I see is that it doesn't separate programming logic from the presentation, at the file level.

I use to do not specify action attribute at all. It is actually how my framework is designed all pages get submitted back exact to same address. But today I discovered problem. Sometimes I borrow action attribute value to make some background call (I guess some people name them AJAX). So I found that IE keeps action attribute value as empty if action attribute wasn't specified. It is a bit odd in my understanding, since if no action attribute specified, the JavaScript counterpart has to be at least undefined. Anyway, my point is before you choose best practice you need to understand more context, like will you use the attribute in JavaScript or not.

When you put empty action then some security filtration consider it malicious or phishing. Hence they can block your page. So its advisable not to keep action= blank.

Related

Most secure value for action attribute in the <form> tag

I wanted to know what is the most secure option for the action attribute as many people says $_SERVER['PHP_SELF'] is not secure. Is it fine to give empty string for action attribute? But the output is different for $_SERVER['PHP_SELF'] and empty string.
I don't think there really is a truly "secure" way of populating the action attribute of a form. For example, I can open web console and modify the form anyway I want to.
That said, I think the real concern you are getting at is if someone were to send a link where an exploit designed to change the value of PHP_SELF has been used. The person who gets the link has no way of knowing that the form has been compromised.
So, I generally like to hard-code my action URL's where I can. If they must be dynamic, you can validate them against a list of URL's that you would expect to make sure it makes sense.
There is also nothing wrong with an empty action attribute, but you might take a look at Forms with action=""
Edit: To sum up my original post:
I think Hard-coded URL's are the best.
A "#" or an empty string would be next (effectively, it is still a hard-coded URL).
I try to avoid PHP_SELF where ever possible, and validate it against known, legitimate URL's when I have to use it.

PHP empty action form Vs PHP self

I have any form for submit using PHP self url. For action URL i have two way:
insert empty like this : <form action="">
insert $_SERVER["PHP_SELF"].
Which way is better and safe?
Don't count on non-standard behavior which is what happens when a browser submits a form to the same page when no form action is specified. Always be clear and concise to avoid unforseen issues. Especially when all of it is within your control.
A third option is probably best: the page that makes the form should know its own url, so enter that. #johnconde is correct in the argument to not rely on non-standard behaviour, but the alterative you give isn't much better: you hope the user didn't do something (or was tricked in doing something) unexpected.
random link: http://www.dzhang.com/blog/2013/05/20/php_self-and-cross-site-scripting that explains this.
Better to just know your page, and echo the actual page you are looking at.

Difference between '#' and $_SERVER['PHP_SELF']

Just a general question. In terms of form actions if the form is submitting to it's parent page I realize that you can use "" or "#" to submit the form. Now my question is when writing a php page that has both the handler and the form I was told it was best to write a form action like this:
action="<?php echo $_SERVER['PHP_SELF'] ?>"
//or
action="<?php echo $_SERVER['SCRIPT_NAME'] ?>"
Now why would you need to add this inline script if you could have the form submit to itself using '#' or just simply not setting the form action. I'm just curious, as adding in that php does create bulky and messy looking form code (which is already bulky and messy looking).
I also understand that the alternate '#' and "" could be used in cases that you aren't using PHP, but I guess the real question is why add the PHP if you don't need it (in instances that the form is submitting to a php page).
thanks,
Brodie
Mahalo guys for all the responses. I realize that using the PHP code to generate the url is probably (in most cases) the route to take, as all it would take is for an update to a browser or to HTML in general to say "" and "#" are invalid operators for submitting to the root page. Also I know that the '#' is for referencing an anchor on the same page, but I figured I'd see what everyone's take on it was.
First of all the easy part: why put something into the value of action in the first place.
Well, the HTML 4 spec says (emphasis mine):
action = uri
This attribute specifies a form processing agent.
User agent behavior for a value other than an HTTP URI is undefined.
Therefore, while practically all browsers will end up submitting the form to the script itself, technically this is a happy coincidence that you should totally not rely on. However, this is not a problem for HTML 5.
In addition, # by itself is not a valid URI as per the W3C's definition, so that should be ruled out as invalid as well.
Now for the other half: how to get the current URL in PHP.
For basic usage, you can use either one of $_SERVER['REQUEST_URI'] and $_SERVER['PHP_SELF'] for this, depending on if you want to preserve any GET parameters in your current URL (PHP_SELF will not include them, but REQUEST_URI will).
In more advanced scenarios (e.g. writing code using a framework) it would be better to use the framework's own URL-generating utility functions to generate the URL for you (this would take routing etc into account, so is preferable).
Update: I misread the HTML 5 spec, which says you can leave the action blank.
Using # is not really the right way to do it, although it will work. You will find that the # on the end of a URL is supposed to be used to scroll the page down to an anchor on the page which matches it. Forms should use a URL in the action field. It's not wrong to do it any other way, but it's more to do with accessibility and usability (some JS librarys use the # url)
tl;dr - Leave it blank.
With modern frameworks and url rewriting, this is actually a bad practice. Your php script will more than likely be different than the URI path to access it.

Validating names in textboxes in PHP, HTML or Javascript

When I type in a name in a textbox on a form, how can I validate that name before the user clicks submit?
I see this all the time in CMS and in some forums and never been able to figure it out.
Joe
That depends entirely on what you want to validate. Are you trying to filter out potentially dangerous characters? Is there a format you want names to adhere to?
If you want to filter it before the user clicks submit, then you'll need to use Javascript.
Read in the value of the textbox, either as the user types it, or after focus is no longer on the textbox, and then inspect the value to see if you're happy with what has been put in. The easiest way to do that is by using regular expressions. Look them up.
You can disable the submit button until the text field validates.
However, it may still be possible to submit the form, so make sure you do validation on the server side too. Again, it depends entirely on what you want to do - PHP has lots of built-in functions for validating strings to filter out malicious characters, HTML entities, and more.
Figure out what you want to do, then look it up in a search engine.
I am assuming you are talking about seeing if a username is available or if the username is valid - the best way to do this is by using a jQuery plugin.
There are plenty of tutorials available online to walk you though the all steps.
Such as jQuery Username Availability check.

hide php file url in html form submit

<form action="/path/hello.php" name='myForm' method='post'>
<!-- onChange="ajaxFunction();" -->
<input type= "text" name="user" id= "txtname" /><br />
<!-- <input type="text" name="user2" id="txtname2" /> -->
<input type='submit' name = "click" />
</form>
Noweveryone who looks at my html source code will know where this php file is located and will know how to call it. How can i stop this ?
If you handle the POST request to /path/hello.php properly, it shouldn't matter whether someone accesses it manually. Just make sure you are checking for things like the existence of $_POST['click'] and any other POST data you expect to exist, clean it, and proceed as normal.
If someone were to call /path/hello.php with spoofed POST data, then how would that be any different than them submitting your own form? There's no need to modify the script's visibility.
Furthermore, if your fear is that someone would be able to view the source of your PHP scripts--don't. The only thing a user would be able to see if they made an HTTP request to your PHP script would be the rendered HTML.
However, even if they could--why wouldn't you want someone to see your source (of course, barring situations where you might have sensitive configuration data within a PHP file)
You can't stop it. If you're going to tell the browser where the form is, you have to put the address in the HTML somewhere and once you do that anyone can see it.
It really shouldn't make any difference though, as your script should be able to cope with whatever values are sent to it. You can't blindly trust the data from the client in any case, so you need to verify the data sent is what you're expecting - no matter whether that's data sent by filling in your form as normal or someone calling it directly.
I can give a good example for why you would want to do this. You may have a service and offer it to a 3rd party, however in order to make this work there is some important configurable data that may come exposed. Here is an example
You own a website and let's say you want to create some type advertising campaign on your website but your "client" wants to advertise this the same thing on their website but the data needs to go into your email database.
you may not want them to know who you use
those services may require you to add account number or some type of identifying parameter towards your account.
May not be a big deal but still could be a security risk. So if you divert or mask it can prevent some of it.
There is no way to avoid this other than leave off action all together. The form will then submit to the current URL.
In any case, why are you worried about someone accessing the script? If you've written it correctly, no information should be exposed, and, no, they will not know how to "call" it - unless by calling it you mean simply accessing it in the browser. If by simply accessing it in the browser, sensitive information is displayed, you've got some serious problems on your hands.
I think your question is that by showing these paths that people will be able to actually view the source of the php file. That is not possible because it is being rendered by the php engine you are using. You have nothing to fear here.
Sorry, this isn't an answer, but a general observation on this same subject...
I have also experienced this and, seem to know where the OP is coming from...
I have seen a number of large CMS where form "actions" don't show the script... almost as if it points to a "friendly" URL...
Such as <form name="contactform" method="post" action="http://example.com/contact/send-contact">
As can be seen the extension is missing but the form is processed correctly...
I guess the htaccess could hide the extensions but some have a mix of visible URLs for standard pages and some "friendly" URLs for other content (including forms).
I'm not sure how these work...
It is sometimes considered best practice to keep .php files above the root directory to protect against the rare occurrence of php being configured incorrectly on the server and displaying php code to the client.
All you have to do is create a proxy script and post to that. I store the action in a hidden field so that I don't need multiple proxy scripts. I can't post the source code because I would be duplicating my answer on another post. You can find it here: https://stackoverflow.com/a/36941336/2452680
you can first give an action to page1 and in page 1 you can get the data and redirect and post the data to page2.
if you are using phpin page1 you can use curl and options to put data and execute it.

Categories