I have a PHP script that gathers variables from a HTTP Post notification sent by PollDaddy. See here for more info on PollDaddy's API: http://support.polldaddy.com/http-post-notifications/
I am worried that if someone finds the URL to my PHP script, it could potentially be taken advantage of. (e.g. sending fake http post requests, or spamming with http post requests)
What are the best ways to secure this script and ensure that valid requests are only coming from PollDaddy?
Any help is appreciated!
It looks like you control the url that it goes to.
You could add a ?super_secret_key=randomstring at the end of the url and check to make sure that exists in the $_GET array on ever request.
However, at the end of the day, this security is based only on "Security Through Obscurity". There isn't really anything inherently "secure" about this method.
Related
I have done some researches on how to prevent fake cross-origin requests and have found a lot of useful information. However, none of them seems to directly resolve my concerns, and because my application has to deal with this specific situation, I would like to understand it completely.
I have a simple php mailing website: mailsite.com
This site will allow other pre-defined addresses, for instance, user.com, to send POST data to it, and process the information that contains to and mesaage; then send them an E-mail from mailsite.com to to with the message message.
Currently, I am using $_SERVER[ "HTTP_ORIGIN" ] and $_SERVER[ "HTTP_REFERER" ] to check where the requests come from; and process them if it is from the pre-defined domains. However, I've read some articles that say:
HTTP_ORIGIN is not even indexed in PHP documentation, because it is pretty much per-browser sort of thing, so browsers that refuse to send those information will not work. HTTP_REFERER is easy to fake.
Tokens are good in preventing CSRF.
However, the request I allow is coming from a third pre-defined website, how does Tokens work in this situation?
My question is: If I allow specific domains to POST data to my site, how can I make sure (or the most secured way) that those requests are coming from the sites I expected? Is HTTP_ORIGIN not even safe enough to use? I dare to think about allowing third website to POST data to my site because I've seen Facebook allowing people to access their database. There must be some possible solutions for checking where the requests come from.
It sounds like you have multiple solutions possible:
Use a token permission system. Give user.com a private token to add as a hidden value to the input form. Upon submitting this form, the browser will give your server the token, and the user shouldn't have to know about the token. You check the token against your own database. If you find the token, allow the mail to be sent.
Use CORS (Cross-Origin Resource Sharing). When an Ajax request is sent to your server from user.com, there should be multiple Access-Control headers. You check if these exist and what their values are using $_SERVER['HTTP_ACCESS_CONTROL_header'] where header is one of the Access-Control header names. If these values match up to your expectations, respond with multiple header('Access-Control-header: value'); calls so that the browser knows you accepted the preflight request, otherwise don't add any extra headers. The browser will send another request after the preflight, and this is when you'll actually send the mail.
If this is being sent from user.com's server rather than a visitor of user.com, most likely the server's IP address won't change (though it may or may not use a defined range of IPs, so be mindful of that.), so you could verify that the $_SERVER['REMOTE_ADDR'] matches a value in your database. You can keep a table of approved IP addresses in your database for this purpose. If you find the IP address in your table, allow the mail to be sent.
Hope this helps.
I'm building a Drupal site that has a little voting system. I have a PHP page which takes in parameters and updates the voting database accordingly. How do I allow this page to be accessed through this AJAX on my Drupal site but otherwise restrict access to outside users just going to this URL to prevent forged voting?
AJAX == regular HTTP request. You cannot distinguish an AJAX request from a "normal access". There is no way to prevent this.
To prevent wrong votes, you need to build such security into your voting system. Require registration, use sessions and nonces or whatever is necessary. But trying to "block non-AJAX requests" is not a solution.
You can rely on 'X-Requested-With: XMLHttpRequest' HTTP header that is appended to each Ajax request by most standard browsers.
Yet, as #deceze pointed out, it's far from being considered 'secure'. It's quite easy to issue 'normal' http request that include this header, either by using Fiddler or programatically.
If you just need to restrict voting by simple refresh of the browser address bar, just change the script to get the vote value using http POST verb.
i am using Ajax to send JSON data over to my server for a php script to parse.
for example this is the JSON which will be outputted:
http://myserver.com/parse.php?user=123&point=100&callback......
and the "parse.php" script will GET the points in the URL and give it to that user which the user id is stored in the user=123.
However , if a person directly use "http://myserver.com/parse.php?user=123&point=100&callback......" on their browser without letting my javascript to initiate it , they can cheat their points , which they can set to any amount they like in the URL.
So how can i protect/authenticate the JSON request??
If you're passing the user points via an AJAX request or something similar client-side, then you simply cannot protect your application against cheating. Your user is telling the script he/she scored 100 points, how can you be sure that's the fair number? Pass over the initial data you're using to compute your score, like valid answers for the questions or whatever it is you're measuring.
If you have a login mechanism in your application, you could check for the valid credentials on the server-side when executing your script, without actually passing the user identifier via GET/POST.
Lastly, in your method you can check for the AJAX header and the referer ($_SERVER['HTTP_X_REQUESTED_WITH'] and $_SERVER['HTTP_REFERER']) to make sure the request comes from your JS code, but this is really just a minor tweak which is easy to compromize. Also, not every browser passes the referer header (depends on privacy settings), so further problems may arise.
Require Users to be logged in to invoke parse.php. If the request doesn't supply a valid session id, refuse to take action.
Don't put any game data and logic in client side.
Never trust the client. You always must calculate server-side.
More infos (don't rely on link title, there is a lot infos in answers) : https://gamedev.stackexchange.com/questions/3695/how-do-you-prevent-your-javascript-html5-web-game-from-being-copied-or-altered
I am supposed to capture data from a form and send the data to a url on a different server.For eg:-I have a form on a page at the url http://www.form.com/register.php.
I capture all the data from this form and for some reason need this data to be processed on a page on another server at http://www.thereceivingpage.com/process.php.
As of now I am using headers to redirect with the parameters in the query string something like this:-Header(Location:http://www.thereceivingpage.com/process.php?name=alice&address=a1&address2=a2) but I need to send a larger amount of data which wont happen as GET request. Can anyone suggest a better way where in I can post data rather than the data in the query string ...thanks
Use cURL. If you have to redirect to the site, it gets a bit trickier but you can still do it. You can get the cookie and redirect information back from the site and then do a GET redirect using header.
Can you not update the action to simply post directly to that form? Otherwise, you might want to look into something like curl: http://ca.php.net/manual/en/function.curl-exec.php
You'll pretty much re-use the header redirect syntax with the parameters but instead you'll tell it to be a post.
redirect to a page on a different server and post parameters to it
thanks to internet standards, that's impossible.
if it's third-party site, let user to interact with it directly. do not interfere between them, it smells
If you want to develop secure applications then you should be aware that http://www.thereceivingpage.com/process.php is vulnerable to Cross-site Request Forgery (CSRF), meaning that anyone, from any site, can post form data to process.php.
process.php should be checking for a token (which www.thereceivingpage.com transmitted to the user as part of the form) and should be rejecting form submissions that don't contain the token to prevent submissions coming from anywhere but www.thereceivingpage.com and thus protecting your users from being manipulated into making requests they didn't want to.
In addition to your concern about the size of the GET requests you cause the client to make when redirecting, it's also not a good practice to turn POST requests into GET requests.
The best solution is to completely rethink the notion of delivering a form from one site to be submitted to a different site.
You can manually set headers and send request or you can use curl
see this
http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html
How would I prevent users from spamming a post request? For example, a form is submitted via Ajax post. Using firebug I can see the post request, but I noticed that this request can be easily repeated by right clicking on it and selecting "open in a new tab" How can I prevent something like this?
When a valid user logs in or begins a session, generate a random token string and place it in a hidden form field. Each time a valid post is made by a valid user, generate a random token string and store it in $_SESSION while also returning it to the client browser. When a the browser makes another Ajax post request, it must also send that token string which you compare against the $_SESSION.
That way you can only make an Ajax post if your server has previously sanctioned it. It prevents anyone who simply knows the Ajax handler's URL from sending HTTP requests to it.
Any web form can be posted to in any number of ways. What you need to do is make sure the server-side script that processes the form has the logic needed to "ignore" spammy requests.
You can't reliably. But you can check for the HTTP_X_REQUESTED_WITH header which is usually send along with ajax requests. It can be spoofed though, and can also not be there for genuine ajax requests.