What is the best solution to form spoofing? - php

What is the best solution to "form spoofing" besides filtering the inputs?
I understand the followings:
Referrer can be spoofed
Telnet can be used to fool the server
Client side filtering can be bypassed
i understand that i should avoid GET
I can use Captcha
How can i prevent somebody to post to my form processing scripts from anywhere?

If someone can manually post a form, they can do it automatically too. There's no way to stop that besides moderation. You can make it harder by using captcha's. But personally I hate captcha's, because they are just a solution made up by lazy moderators to make the users solve their problems.

Here is a way to use tokens.
http://shiflett.org/articles/cross-site-request-forgeries

Not much really. Every client-side check can be spoofed or bypassed. Some authentication method is best, either using HTTP Auth or a simple system you coded yourself with sessions.

I don't know what the best solution is necessarily, but you can use a session variable on the script that should have generated the form and check it in the script that the form POSTs to. You can md5 the variable contents and make it something somewhat random for increased security as well.

The real question is why do you want to prevent people from being able to post to your webpage from anywhere? Your webpage should be prepared to accept any input no matter where it comes from. There are measures you can take to reduce automatic posting such as tokens, but there is no way you can prevent it completely.
Instead of trying to prevent it, though, I would welcome it. Advertise your cross-site post API and profit.
Postel's law:
TCP implementations should follow a general principle of robustness: be conservative in what you do, be liberal in what you accept from others.

Set a hidden input on the form that's equal to the md5 value of a string made up of the session id + a secret "salt" string value. Then, when you process the form, you can get the session id, add the secret value, and compare the mp5 out of that to the value that was passed with the form.

Related

is it safe to use $_POST for button action?

Is it safe to use $_POST for button action ?
for ex.
<button name="submit">Table A</button>
php (what my code here does is, if i click the button(Table A) the table A will appear then, in default is not viewable.)
if(isset($_POST['submit'])) {
<table>
code....
</table>
}
FOR MY QUESTION: is it safe ? to the attacker ? like xss, sql injection, or something ? I want an advice, to have more safer website. (or atleast safer from attackers)
It is safe provided you don't echo the output or use it unescaped within a SQL statement. Also your code should really be...
if(isset($_POST['submit'])) {
...
}
to avoid errors if it isn't set
Developer has always to sanitize and to validate the input he's getting from the request.
Depending on the purposes - you need either to enforce the sanitation or to make less cleaning (for example for DB you need to clean it up/escape additionally, for HTML output to make XSS protection, etc.)
You may read up on:
How to sanitize the input (POST/GET variables, referral, cookies, user agent, and other headers)
Cross-Site Request Forgery (CSRF) prevention;
additionally you may want to use Captcha or other protection from automatic submits, etc.
For your specific purposes, in the question itself - you are not using the value of $_POST['submit'] in any way, except checking of presence, so no additional validation is needed, it's fine like that.
Short answer
NO
POST variables are not 'safe' on their own.
Long Answer:
There are many issues around authenticating POSTed variables on your PHP script. The most well known is Cross Site Request Forgeries whereby the value is sent to your page but you have no idea where the value came from, or who sent it.
To counter this you need to set up single use unique keys to send and receive, typically using PHP SESSIONS or similar concepts that can not be touched by the end user.
The second issue is that you should never ever ever trust the contents of a POSTed variable. you need to fully escape the variable as well as ensuring that the variable is given absolutely minimum access to your code, so if it is a compromised value, it is hopefully cleaned and/or it can not harm your script.
Your Code:
Looking at your question in detail you suffer from CSRF (point 1, above) in that your PHP code has no idea if the submitted button came from the page your button exists on and therefore the PHP has no idea if the browser should see the contents of "Table A". (If everyone can see it, why hide it in the first place?)
There is also the factor your code could be used by a nefarious party to send many, many POSTed submits to the script, over a short space of time (100,000 over 2 seconds) causing a DOS attack, again due to there being no validation of where the POST came from and its implied authenticity.
Further points: You need to clarify what you deem as "safe", it is a very relative term.
You can use the button with POST. But make sure, you have validated the referrer URL of the action. Because someone may try to copy your form and submit in loop. This will down your site.
So you should check the referrer URL matches with your site URL.
Also always use form token to validate the form (Like captcha)

Secure way to stop users from forging forms

How can I prevent users from forging forms on the PHP or jquery side, I am using Jquery's ajax functionality to submit the forms, and this means that tech-wise people can change some variables such as the value of something (that shouldn't be changed / is a user id or something like that) through the use of firebug or web inspector and likewise.
So how can I prevent users from changing these variables or making sure they are unchangeable through a secure and good way?
Thanks
As the others have already stated, you can't prevent the user from tampering.
You are receiving data from me, and I can send you anything I want, I can even do an HTTP request by hand, without even using a browser, and you can't do anything about it.
If you don't want a user to be able to alter an information, don't provide it to him.
You can store it in PHP's session, which is stored server side (do not use cookies, they too are sent to the user) or save it in a database, both of them are not accessible to the end user.
If you still want to pass the data to the user, compute some sort of hash (a secure hash, using a secure hashing algorithm and a secure message digest as Gumbo noted, this rules out algorithms like CRC32 or MD5 and MACs like your name or birthday) of the data and store it server side, then when the user submits back the data, check if the hashes match.
But do know that this solution is not 100% secure. Hashing functions have collisions, and bad implementation exists.
I would recommend to stick to the golden rule: if it's not there, it cant break / be tampered / be stolen / etc.
You cannot prevent users from doing so.
Store these variables in a Session.
You can never trust the client. Validate the form on the server to ensure the data is sane. This means checking that a given user ID has permissions to post their form, etc.
I'm going to go with... you can't. You never trust the user's data; client side verification is always only the first line of defense.

How to make sure that a variable is posted from a specific JavaScript page in PHP

There are tasks that can only be done by JavaScript.
My problem is that after doing the task from JavaScript, the JavaScript code has to send the variables to a PHP page and, from my knowledge, it can only be done by post, get, and cookie which means that a user can possibly fake the variable and submit it.
I want to make sure that the variables the PHP page receives is from the JavaScript page.
No luck so far. What is the solution?
You're right, this is certainly a problem.
Whitelisting/validating the input from the client could solve some of your problems, by making sure that the value is at least within a certain range of acceptable values.
What specifically is your use case that you're concerned about? Perhaps we could help you more if we knew more about your scenario.
We could help you better if you would describe your specific scenario and what kind of data input you need to avoid.
In general you should always try to validate data on the client (JavaScript) just to provide a better feedback to the user (like highlighting a required form field left blank). Consider this to be just as a courtesy for the user.
Regardless of that you should never trust the data coming from the browser and do all the security relevant validation on the server and don't care what kind of client software has been used to collect that data (being that your JavaScript code or some hard coded GET/POST data).
As the other answers have stated whitelisting is really the only thing you can do -- If someone is deliberately attacking your website there is no requirement that any content you get is valid.
No amount of client side validation or cookies works either as an attacker does not need to use a browser to do Bad Things.
You can generate an authenticity token when serving your page. Then check that the response contains the same authenticity token. A la rails.

PHP $_POST & Denying Fake Forms Security

I'm currently writing a web application which uses forms and PHP $_POST data (so far so standard! :)). However, (and this may be a noob query) I've just realised that, theoretically, if someone put together an HTML file on their computer with a fake form, put in the action as one of the scripts that are used on my site and populate this form with their own random data, couldn't they then submit this data into the form and cause problems?
I sanitise data etc so I'm not (too) worried about XSS or injection style attacks, I just don't want someone to be able to, for instance, add nonsense things to a shopping cart etc etc.
Now, I realise that for some of the scripts I can write in protection such as only allowing things into a shopping cart that can be found in the database, but there may be certain situations where it wouldn't be possible to predict all cases.
So, my question is - is there a reliable way of making sure that my php scripts can only be called by Forms hosted on my site? Perhaps some Http Referrer check in the scripts themselves, but I've heard this can be unreliable, or maybe some htaccess voodoo? It seems like too large a security hole (especially for things like customer reviews or any customer input) to just leave open. Any ideas would be very much appreciated. :)
Thanks again!
http://en.wikipedia.org/wiki/Cross-site_request_forgery
http://www.codewalkers.com/c/a/Miscellaneous/Stopping-CSRF-Attacks-in-Your-PHP-Applications/
http://www.owasp.org/index.php/PHP_CSRF_Guard
There exists a simple rule: Never trust user input.
All user input, no matter what the case, must be verified by the server. Forged POST requests are the standard way to perform SQL injection attacks or other similar attacks. You can't trust the referrer header, because that can be forged too. Any data in the request can be forged. There is no way to make sure the data has been submitted from a secure source, like your own form, because any and all possible checks require data submitted by the user, which can be forged.
The one and only way to defend yourself is to sanitize all user input. Only accept values that are acceptable. If a value, like an ID refers to a database entity, make sure it exists. Never insert unvalidated user input into queries, etc. The list just goes on.
While it takes experience and recognize all the different cases, here are the most common cases that you should try to watch out for:
Never insert raw user input into queries. Either escape them using functions such as mysql_real_escape_string() or, better yet, use prepared queries through API like PDO. Using raw user input in queries can lead to SQL injections.
Never output user inputted data directly to the browser. Always pass it through functions like htmlentities(). Even if the data comes from the database, you shouldn't trust it, as the original source for all data is generally from the user. Outputting data carelessly to the user can lead to XSS attacks.
If any user submitted data must belong to a limited set of values, make sure it does. For example, make sure that any ID submitted by the user exists in the database. If the user must select value from a drop down list, make sure the selected value is one of the possible choices.
Any and all input validation, such as allowed letters in usernames, must be done on the server side. Any form validation on the client, such as javascript checks, are merely for the convenience of the user. They do not provide any data security to you.
Take a look # nettuts tutorial in the topic.
Just updating my answer with a previously accepted answer also in the topic.
The answer to your question is short and unambiguous:
is there a reliable way of making sure that my php scripts can only be called by Forms hosted on my site?
Of course not.
In fact, NO scripts being called by forms hosted on your site. All scripts being called by forms hosted in client's browser.
Knowing that will help to understand the matter.
it wouldn't be possible to predict all cases.
Contrary, it would.
All good sites doing that.
There is nothing hard it that though.
There are limited number of parameters each form contains. And you just have to check every parameter - that's all.
As you have said ensuring that products exist in the database is a good start. If you take address information with a zip or post code make sure it's valid for the city that is provided. Make countries and cities a drop down and check that the city is valid for the country provided.
If you take email addresses make sure that they are valid email address and maybe send a confirmation email with a link before the transaction is authorised. Same for phone numbers (confirmation code in a text), although validating a phone number may be hard.
Never store credit card or payment details if it can be avoided at all (I'm inclined to believe that there are very few situations where it is needed to store details).
Basically the rule is make sure that all inputs are what you are expecting them to be. You're not going to catch everything (names and addresses will have to accept virtually any character) but that should get most of them.
I don't think that there is any way of completely ensuring that it is your form that they are coming from. HTTP Referrer and perhaps hidden fields in your form may help but they are not reliable. All you can do is validate everything as strictly as possible.
I dont see the problem as long as you trust your way of sanitizing data...and you say you sanitize it.
You do know about http://php.net/manual/en/function.strip-tags.php , http://www.php.net/manual/en/function.htmlentities.php and http://www.php.net/manual/en/filter.examples.validation.php
right?

php check form submit from url

How do I ensure that the attacker or spammer do not attempt to sent data from http://localhost computer? I am developing Flex/flash application which would then submit the data to PHP. I know they have the ability to decompile actionscript, would the HTTP_REFERER help?
Not all browsers supply HTTP_REFERER and it can easily be spoofed, so it will not secure your form.
The best thing you can do, and really the only thing you can do, is to make sure that your PHP code does not trust any input. You should check that any values submitted to your form are within an acceptable range of values, double check login information if appropriate, etc.
If you're worried about bots, use recaptcha or limit the number of submissions for any IP address to 3 a minute (as an example - choose an appropriate speed for your situation).
In short: you can NEVER be certain where a form submission originated. You must be prepared to deal with submissions from attackers.
You could use referrer, but even that could be spoofed. If it was me I would sha1() some random string or something in your flash and pass that with your form, then you could sha1() on the php side and check them.
Perhaps you could even make it something dynamic, like
sha1(date('Y-m-d')."MySaltPhrase");
parse_url() combined with string manipulation should work. Try this:
$url = parse_url($_SERVER['HTTP_REFERER']);
$host = implode('.',array_slice(explode('.',$url['host']),-2));
if (strtolower($host) == 'google.com') {
// code......
}
use CAPTCHA for verification. you can't tell if the source or referrer is the localhost or a public IP address when a form is submitted. the localhost you'll see is your own.
the answer is simple - you cannot.
because every form actually being sent from user's local computer. that's HTML thing and you'd better understand that. will save you ton of time.
in general you don't need any protection at all.
but for some particular cases protection tactics will be different
to prevent spam use a CAPTCHA
to prevent CSRF use unique token, stored both in the session and form's hidden field
add your own particular task here to get a particular protection method. from what attack you want to defend?

Categories