Prevent Users From Seeing Requested URL and String Parameters - php

In my site, I am submitting information information that cannot be tampered with. Is there a way that I can prevent users from seeing the URL my app is requesting? In Google Chrome, it is very easy for users to see this.
I am submitting data to another website. They encrypt the data in their end but there isn't a way to encrypt the string parameters before and while they are being transmitted. This makes it easy for users to just copy the requested URL, change around the parameters, and do as they please. What options do I have to encrypt the string parameters?

You can't prevent them from seeing the URL if you are making the request from their client. You also can't trust anything on the client, so you can't encrypt something on the client.
Is there any reason you can't just send the data to your server, validate it, then forward it along to the target server? I'd say that is the correct option.

Dear user you can encrypt the url with md5 & mysql database
if you need random urls for every request
check
for more information its verry simple
http://il1.php.net/md5
http://il1.php.net/manual/en/book.mysql.php
with the random function pretty simple
i hope you get the idea or you can just use the post method and store data on the mysql database
and once its on the final step you can make it run in the background as all the data will not be seen by the user. and make sure in production version of website you put on that php file
// Turn off all error reporting
error_reporting(0);
Have a nice day

Related

How to prevent users to change url parameter in PHP?

I am developing a site where I am sending parameters like ids by url. I have used urlencode and base64encode to encode the parameters.
My problem is that how can I prevent the users or hackers to play with url paramenters Or give access only if the parameter value is exist in database?
I have at least 2 and at most 5 parameter in url so is this feasible to check every parameter is exist in database on every page?
Thanks
You cannot stop users from playing with your QueryString.
You can only validate them in your script before you do anything with them.
This also applies to POSTed variables as well, they can be hacked almost as easily.
So Validate, validate, validate.
In general if you concern about internal data put them in a session variable. But remember always everything out there is evil. You alway have to check if any input contain SQL injections.
If you use session cookies make sure that hey are http only. So no JavaScript can copy the session cookies and if possible never put them in the url itself. It's quiet easy to copy the url and hijacking a existing session.
This depends a bit on what you are using the parameters for. If they are private and should not be accessible to other users, you should link the data to a specific user and deny access to everyone who isn't authenticated as the correct user.
Also, always remember to sanitize user inputs, which includes URL parameters. Use prepared statements when passing user inputs to a database and encode it before serving it back to other users.
The best I would to is to validate on server side for the user entered paramters. Also I would check if the requests originated from my site (XSS & CSRF). Transmitting data post would be good but provides minimal security IMHO.
Therefore, validate and authenticate the originating location to ensure that it does not come from an outside source

How secure is file_get_contents with GET parameters over https://

I'm using "file_get_contents" in the following way:
(the script below is posted on, for example https://siteA.com/checkifvalid.php ...notice the URL is httpS)
<?php
//there is a login form on this URL and the entries put in the form are used to set the username & password variables below.
$username = "someusername";
$password = "somepassword";
$secretkey = "slkd89087235";
$yesorno = file_get_contents("httpS://siteB.com/checkdatabase.php?username=$username&password=$password&secretkey=$secretkey");
if ($yesorno == 'yes') {
//details are valid, so something
} else {
//details aren't valid, display they aren't valid
}
?>
The "checkdatabase.php" script gets the username & password using _GET and grabs the variables from the URL and then cross references those login details to see if they are valid or not. If they are, it echos "yes" if not, it echos "no".
The checkdatabase.php script is set to only run if both the username, password & secret key parameters have been passed, and then only if the secret key value that has been passed matches the secret key stored within that php script.
There will also be a limit to the number of times "http://siteA.com/checkifvalid.php" can be entered in a given span of time to prevent a type of "brute force" attack guessing user/pass combos.
My question is, how secure is the above method seeing as both URLs are using httpS?
Should I encrypt the values sent? Or is what is above secure already?
[UPDATE] After a few comments, I've realised I read and answered your question too quickly. I'ev changed my mind.
To answer your exact question
HTTPS is as safe as your private key
Unless your attacker has access to the private SSL key, HTTPS is safe. If your server is ever compromised, then so is HTTPS until you generate a new key.
Prefer POST over GET
Second of all, if you're really going to use HTTP for this, you should use POST instead of GET.
1) The semantic reason: you're asking the other server to do something. That operation is not idempotent but the GET method is (at least in theory). As #Gumbo pointed out in the comments, you're only doing a check and not running any operations on the destination server so the comment about idempotence doesn't apply here.
2) Your password could show up in access logs. Even though different stacks seem to handle HTTPS loggin in different ways by default, you shouldn't take any chances and assume GET requests will end up in a log file somewhere.
You can use cURL to do the POST like this: PHP + curl, HTTP POST sample code?
Don't post/store plain text passwords
Store and post an encrypted password
Your master DB should not store plain text passwords. Instead, encrypt it before saving it, then encrypt the submitted user input before comparing.
Use a shared public key
Instead of posting a plain text usermame/password/secret, you could implement a shared key. This is essentially the same mechanism used by HTTPS. Using this method you could safely send this request over HTTP.
Read up on public-key cryptography, it's really easy to understand. Implement it using openssl_public_encrypt().
Read more about that last one here: Output of openssl_public_encrypt() and openssl_private_encrypt()
Different approaches
Query the remote DB directly
By far the simplest, setup the MysQL daemon on siteB to accept remote connections from siteA only, and query the siteB DB directly from siteA. This doesn't involve HTTP at all. Just makre sure your MySQL password is secure, restrict by IP, and don't store plain text passwords.
Write an OAUTH provider service
From Wikipedia:
[OAUTH] provides a process for end-users to authorize third-party
access to their server resources without sharing their credentials
(typically, a username and password pair), using user-agent
redirections.
Here's the first article I found about writing your own: http://toys.lerdorf.com/archives/55-Writing-an-OAuth-Provider-Service.html
You might be better off using something like the OAUTH component in Zend Framework or something similar if that's the path you go down.

PHP backend / frontend security

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

Connect php with Android, security methods

I'm sending data from an Android app to a php script which recieves the information and procces it, I've found a security issue: if someone discovered the url (for example: mydomain.com/recievedata.php), anyone would be able to send data to my system.
What's the ideal method to ensure the client sending the data is the app?
Thanks!
One easy way that I've seen some companies do is to include a secret key. For example, you might have a secret=3CH6knCsYmvA2va8GrHk4mf3JqmUctCM parameter to your POST data. Then all you need at the top of receivedata.php is
if($_POST['secret'] != '3CH6knCsYmvA2va8GrHk4mf3JqmUctCM') {
header('HTTP/1.1 403 Forbidden');
error_log("ERROR: wrong secret: " . $_POST['secret']);
exit("Access denied");
}
You can easily generate the random string from random.org.
Of course, this is not the most secure method and that string might well be stored in plaintext in the APK (don't use this to send launch codes!), but it's easy and good enough to keep most people out. This might be adequate for, say, sending player scores for a game.
It's more like a PHP question. Here are the things you should do for security ;
Add a hash between your app and your PHP to sync (AKA secret key)
Make sure your script controls every input data
DO NOT send datas to query without escaping them (SQL Inject)
Try to use POST instead of GET or REQUEST
Keep your functions private as much as possible
Always parse the data you receieve (Check if its a number, or string or array etc)
With these, noone will be able to use any of your PHP files without your app. And they won't be able to receive any data without your permissions
The only proper way is not trusting the data you receive. Always treat it in a way suitable for crafted data coming from a bad guy.

Is there any way to have persistent (regardless of how small) client-side storage via the web?

Okay, since none of you guys like my question, let me rephrase it.
User logs into an HTML form. With JavaScript, their password is hashed locally (salted too). The server knows what the password + salt should be, user is already registered, blahblahblah. Now the user requests a page. The server sends a random ID to the user. When the user loads the next page, this random ID is appended to the key they have locally stored, it's hashed, and THAT is sent to the server. The server knows what they key is and the random ID, performs the same hash, and compares. If they match, congrats, it came from the proper computer. If not, then someone's been sniffing your TCP/IP traffic.
All of this is obviously without SSL, otherwise this would be highly redundant.
My question - HOW DO I STORE THE KEY ON A CLIENT PC?
Original Post:
Hello;
I'm working on developing a PHP Content Management System, and came up with a secure login system. The only problem is that it would require some form of client-side storage (for a very small key, 40 characters in length) - otherwise the user would have to type in their password on every page load.
Is there a way that, using either PHP or JavaScript, I can store a small 40-character string on a client's PC an retrieve it later?
EDIT: COOKIES ARE NOT AN OPTION. This 40-character string can NOT leave the client's computer, and all set cookies are sent with each HTTP header.
I REPEAT - COOKIES ARE INSECURE AND NOT A VIABLE OPTION FOR THIS.
Let me rework it like this - client submits an HTTP form. With some scripting language (e.g. JavaScript), the password is stripped from the form, NOT sent to the server, encrypted, and is kept CLIENT-SIDE, which I can retrieve and verify (by hashing it with a key sent to the user from the server). This verification is sent to the server, never the key.
There's already a browser-based system that uses keys to secure data transfer. It's called SSL.
You can use a couple of different tricks to keep state on the client, you can keep a top level frame and store a javascript variable there.
You can use Flash local "SharedObject",
Silverlights' IsolatedStorage
or the equivelant in Google Gears.
but..
Don't follow this line of thinking. You need SSL. You are not going to build something secure, you are going to build something that shoots you or someone using your app in the foot.
First I'll answer the question of "can I store client side data without using a cookie":
You could use a Flash SharedObject, but of course requires Flash, and the user has to click a confirmation box to allow it.
HTML5 features client-side databases, so there's another emerging option for you.
Use Google Gears on the client side and use their local database API
BUT - for your purposes you could engineer a login form which doesn't transmit the password but sends a hash of it. Your PHP script would send a form which included a secret salt value, and then you have some javascript which hooks into the submit event and replaces the password entered with the salted hash.
I'm not a PHP developer but I would advocate that you search for pre-existing authentication systems. They will more often than not be a bit more secure than what you would write (as that would be their primary purpose). It would also allow you to review the code and see how they did it and figure out why.
Edit: You almost always want to handle authentication on the server. It's acceptable to transfer session information to the user in the form of a cookie or url param but the actual processing should be done on the server. You are opening yourself up to major risks otherwise.
Use a cookie if you want to save it between browser visits. It'll be stored on the client's machine.
Use a session if you want to save it for a shorter duration. It'll be stored on the webserver.
If you wanted to create something that never traveled over the internet, you would basically have to do it all in JavaScript.
First, create a piece of code that starts something like Google Gears. Use the database in Google Gears to store the key.
Next, on the rest of the pages, have a piece of javascript that checks the key in the Google Gear database. If the key is not valid, delete the key, redirect the user, and make them log in again.
Cookies are the way to do that, but you won't store any password in a cookie, that's (almost) an order ;-).
You could use session to store information between page load on the server side.
http://fr.php.net/manual/en/book.session.php
Adding to what Bryan says, if you can use the HTML 5 spec, then you can take advantage of local storage.
http://ajaxian.com/archives/webkit-does-html5-client-side-database-storage
I see problem with your approach. First load of initial JavaScript can be sniffed, so salt algorithm is not protected from hacker. Then ID is also "public". I.e. seems like you have next schema (please correct me if I'm wrong) :
password + SHA1 => hashed password
hashed password + (ID from server) + (salt from server) => mega hashed password
I really have a problem to see why "mega hashed password" is more secure than hashed.

Categories