PHP backend / frontend security - php

Hello all,
While taking my time in the bath I though of something interesting. In PHP, how do you tell if the users' forms submitted is valid and not fraud (i.e. some other form on some other site with action="http://mysite.com/sendData.php")? Because really, anyone can create a form that will try send and match $_POST variables in the real backend. How can I make sure that that script is legit (from my site and only my site) so I don't have some sort of cloning-site data-steal thing going on?
I have some ideas but not sure where to start
Generate a one-time key and store in hidden input field
Attempt (however possible) to grab the url on which the form is located (probably not possible)
Using some really complicated PHP goodies to determine where the data is sent (possible)
Any ideas? Thanks all!

Most of these attempts from hackers will be used by curl. It's easy to change the referring agent with curl. You can even set cookies with curl. But spoofing md5 hashed keys with a private salt and storing it in session data will stop most average hackers and bots. Keeping the keys stored in a database will add authentication.

There are few simple ways like:
Checking $_SERVER['HTTP_REFERER'] to ensure your host was the referring script
Adding hashing keys in the forms and checking them with the server session variable stored.
But all the above can be manipulated and spoofed in some way. So, you can use CSRF Validations. Here is a very good article on this.
Other additional techniques I have encountered are:
Adding time limits to forms and ensure they are submitted with in that time.
On every interaction with the form, send AJAX request to validate and reactive the form's timelimit.

HTML5 provides a new input type . The purpose of the element is to provide a secure way to authenticate users.The tag specifies a key-pair generator field in a form.
When the form is submitted, two keys are generated, one private and one public.
The private key is stored locally, and the public key is sent to the server. The public key could be used to generate a client certificate to authenticate the user in the future.
Keygen tag in HTML5
RFC

Related

How to make sure POST data is sent from my website's form, aside from HTTP_REFERRER and using a nonce?

I need to make sure a request comes from a user submitting a form on the website rather than an automated POST request.
I could use
HTTP_REFERRER - but this is not reliable
hidden input field with random value from session - but what's to stop a spammer from going to my form, getting the value from the hidden field, and pasting it into his "program" as part of his automated request?
Any other options?
You could use an HMAC approach whereby you hash the first couple of bits of the POST payload using a hashing algorithm secured by a secret key known only between your php library and your backend. Store the calculated hash in the http headers, not as part of the form payload. All you need to do then is validate the data being submitted server-side by calculating the hash value using the secret key and if the hash value doesn't check out, you know it's a bogus submission. See this for details.
Also, basic cookie security parameters like HttpOnly instructs browsers to not permit access to your set cookies via scripts in transit (VBScript, JavaScript etc) so your tokens could be a little bit more secure in transit.
I'm afraid there is no way: if you examine your option number #2
hidden input field with random value from session - but what's to stop
a spammer from going to my form, getting the value from the hidden
field, and pasting it into his "program" as part of his automated
request?
what you describe is exactly what a browser would do. It would "go to your form", "get the value from the hidden field", and submitting it to your server.
And you can't distinguish between two identical modi operandi.
You can make life difficult for the spammer in a number of ways.
For example, the hidden field might be populated by a Javascript snippet; all non-JS browsers (and all your customers with JS disabled) will be bounced.
You could require a session authentication for starters; that way you'll be able to block the spammer later on by pulling his account.
Just for the laughs (I do not recommend doing this - clunky, risky, error-prone, you make bad enemies), you could employ psychological tactics: whatever response your system is expected to give in case of success (e.g. a spampost becoming visible), you can give also in case of failure but only towards the same IP address that elicited the response, and only for five minutes. Most automated spam-tools won't even check; and the majority of human "spambot tuners" will be satisfied once they see their spam appearing, and go on chuckling to their next victim. If they check later, their bots will still appear to work. With a bit of luck they'll believe there's a human webmaster psychotically hunting and cancelling their spam, and again they'll move on.

Best ways to protect against CSRF attacks in PHP

What is the best way to protect again CSRF attacks in PHP.
It has been recommend to use form tokens, so basically generate a random value and store it in a hidden field. Then also store this random value in the users session.
Finally in the form action, make sure the session and form token match.
if($_SESSION['token'] !== $_POST['token']) {
die("bad... spanking...");
}
Is there a better/easier way, as this requires a lot of code modification in my application (lots of forms and actions).
No. To protect against CSRF, you need to make sure you only trust credentials that are automatically appended to requests (like cookies) when you have reason to believe that the user actually submitted your form. The only way to do that is to have the form carry some kind of secret that the server uses to authorize processing.
If you use a framework or library to compose your form it might help by generating the random number, setting the cookie or session property, and adding the hidden input to your form but those three steps do need to happen.

PHP - securely sending data via forms for various user actions

Say I have one form that changes its content (fields and options) based on the user's current state in a multi-state process. Say that it always leads to the same action, which means the action needs to figure out what event occurred and on which entity.
<form action='/somecontroller/someaction' method='post'></form>
What is the most common way of transferring this sensitive data to the controller? I'm reluctant to even suggest hidden fields, as those can be changed by anyone. Two way encryption of some sort which is then decrypted in the action and used to determine the rest, server-side? Perhaps serialize sensitive info, encrypt it, and put it in a single hidden field on the client side of the form, then decrypt and unserialize in the controller?
<?php
$hiddenData = unserialize($this->decrypt($_POST['hiddenData'], SALT));
unset($_POST['hiddenData']);
$data = array_merge($hiddenData, $_POST);
...
Basically - how do I send some data with a form securely without exposing it to outside alterations, that is, without making sure something can go wrong if it is altered? Is there some kind of best practice regarding this?
You never send that data to the client at all.
Store it server-side within the session management capability (for PHP, you can access that using the $_SESSION variable) and only send the session token (long random number, PHP has routines for generating/maintaining good session identifiers as well) to the client (typically done in the form of a cookie). For keeping track of data in a multi-step process (including the state that the user is in), you never want to expose that to the client.
Interesting question. What I would do is a combination of the following (if sessions are not a solution for you):
employ a AES_256 / modifyed AES_256 crypt/decrypt on a serialized representation
make a MD5 + SALT (or similar) hash of the variables that you could compare with a stored hash to determine if any manipulation took place
use something like the user's IP as SALT to generate the hashes or for the crypt functions, thus if a user's IP should change you'll know that (beware: an IP address might change under some circumstances)

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 plan a "secure" HTML FORM

I use $_POST to read data sent through HTML forms to the server, narrowing down attacks exposure.
How can I strengthen security, using some kind of tokens in the form?
The tokens could be readable however with a sniffer.....
**** EDIT *****
I agree the message above is generic...I'll try to give more details!
Ok, a PHP/Server generates emails containing some data for a sort of user-revision; this is accomplished with an HTML email containing HTML forms. When users receive those emails, they edit data in the forms, and send it back to the server, that in turn it will store it in the database.
While for other types of interaction users/server, login/authentication is required, in this case some particular email clients, like mobile phones, do allow reading HTML email messages and process forms, unfortunately without allowing client authentication (server side login) prior processing the form.
What happens on the server side when forms are received?
Well $_POST is used, removing potential GET weakness, however using $_POST will not prevent other kind of attacks, just because a sniffer can easily "read" data being sent.
Data on the server side is parsed and stripped accordingly, removing unsafe Javascript and quoted text to prevent injections and other sort of attacks.
That's why I was looking for a sort of token/nonce technique, however I thought that tokens are sniffable within the form..... and that's where my help request starts!
You are probably refereing to CSRF (Cross site request forgery). Chris Shiftlett wrote an article about it which explains the concept.
Here are a few things you should look into.
SSL Certificates
CSRF Protection
Ok, I have discovered that Wordpress offers it's own API for NONCES.
What I do now is to add an input field in the form containg the NONCE; when user sends form to the server, the NONCE is validate back.
There's a little chance an attacker could gain access using NONCE contained in the form ** ONLY ** during the lap time occurring between NONCE issue/verify. Quite difficult though: the attacker should sniff data, grab the NONCE and use it immediately to load "something" in the database...
What could it be loaded, assuming content is being stripslashed and de-javascripted?
Moreover, as WP NONCES are created using constants:
wp_create_nonce ('my-nonce');
this will require some additional tasks to use variable generated NONCES in such a way for the attacker it will be more difficult to track the pattern to generate the NONCE...
What do you think?

Categories