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.
Related
I would like to ask this because if no quite sure that it secure.
I am planning on changing my page to ajax based registration. So my data will be inserted using jquery ajax post.
But if someone uses firebug and see where my post is being sent, they can use other form of firefox addons to post data on that url and can easily register without going to my page.
Although I can validate the request first where it is comming from though but that would be extra codes and work.
I will also add server validations for my form since someone can register without validation using the direct url that they will see on firebug.
I just wanted to know if there is already a standard procedures in applying ajax based data post.
But with ajax based select / fetch is cool and very useful.
Currently this is what I am planning on doing on my registration page.
validate that all request's must come from my registration page.
might use a transaction / request code
might use cookie
might use session
might use date time comparisson
if validation fails I should have a form validation on server side
to clean my the posted data before inserting to db
Never trust a UI.
Whether you do an Ajax post or a standard post, people can figure out what you are posting and create their own client. Even if you use https, the person controlling the browser can see what is posted and decipher the protocol.
You need to create your service so that it is not vulnerable to a user handcrafting a client.
If a user can use their browser to register on your site via Ajax, they can spoof the registration using some other programming language. There isn't anything you can do to make it so they can only register from your site via Ajax.
You can implement tricks to make it difficult for them to figure out, but you can't make it impossible. They can spoof the referrer, load other pages to get the required cookies/session variables, spoof Ajax request headers etc.
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.
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
I have a PHP script setup using Jquery $.post which would return a response or do an action within the targeted .php file within $.post.
Eg. My page has a form where you type in your Name. Once you hit the submit form button, $.post is called and sends the entered Name field value into "mywebsite.xyz/folder/ajaxscript.php"
If a user was to visit "mywebsite.xyz/folder/ajaxscript.php" directly and somehow POST the data to the script, the script would return a response / do an action, based on the submitted POST data.
The problem is, I don't want others to be able to periodically "call" an action or request a response from my website without using the website directly. Theoretically, right now you could determine what Name values my website allows without even visiting it, or you could call an action without going through the website, by simply visiting "mywebsite.xyz/folder/ajaxscript.php"
So, what measures can I take to prevent this from happening? So far my idea is to ensure that it is a $_POST and not a $_GET - so they cannot manually enter it into the browser, but they could still post data to the script...
Another measure is to apply a session key that expires, and is only valid for X amount of visits until they revisit the website. ~ Or, just have a daily "code" that changes and they'd need to grab this code from the website each day to keep their direct access to the script working (eg. I pass the daily "code" into each post request. I then check that code matches in the ajax php script.)
However, even with these meaures, they will STILL have access to the scripts so long as they know how to POST the data, and also get the new code each day. Also, having a daily code requirement will cause issues when visiting the site at midnight (12:00am) as the code will change and the script will break for someone who is on the website trying to call the script, with the invalid code being passed still.
I have attempted using .htaccess however using:
order allow,deny
deny from all
Prevents legitimate access, and I'd have to add an exception so the website's IP is allowed to access it.. which is a hassle to update I think. Although, if it's the only legitimate solution I guess I'll have to.
If I need to be more clear please let me know.
The problem you describe is similar to Cross-Site Request Forgery (CSRF or XSRF). To protect you against this you could put a cookie into the browser and have the cookie value sent in the post form too (by hidden field or just add it to $.post). On server side check both those fields, if they match the request probably came from your site.
However the problem you describe will be quite hard to protect against. Since you could easily make a script (or use Crul) to forge all kinds of requests and send to your server. I don't know how to "only allow a browser and nothing else".
Use the Session variable as you say plus...
As MyGGAN said use a value set in a cookie (CVAL1) before rendering the submit forms. If this cookie is available (JS Code Check will verify) then submit.
On the server side:
If this cookie value exists and the session variable exist then the HTTP Request came from your website.
Note: If the script (form) is to presented under another domain DO NOT allow the cookie value (CVAL1) to be set.
Do not allow HTTP Requests on the Server Side Scripts if extra Http Headers Are not available (like x-requested-with: jquery). JQuery sends a request with an X-* header to the server.
Read more on Croos-Site Request Forgery as MyGGAN suggests.
I am not really sure REMOTE_ADDR would work. Isnt that supposed to be the end users IP addr?
Firstly, you could make use of
$_SERVER['HTTP_REFERER'], though not always trust-able.
The only bet that a valid post came from your page would be use a captcha.
try to use HTTP_SEC
// SECURITER
if ($_SERVER[HTTP_SEC_FETCH_SITE] != "same-origin")
die();
if ($_SERVER[HTTP_SEC_FETCH_MODE] != "cors")
die();
if ($_SERVER[HTTP_SEC_FETCH_DEST] != "empty")
die();
i have create a form (so it's PHP and HTML hybrid-code). it has ability to send '$_POST'. And when i click it, it work perfectly on sending and displaying input.
But there's something happening when i click Ctrl+R in firefox for represhing the page. I got this confim dialog : "To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier"
my question
what is it, (this confirm dialog ?)
what i have to do on my code so it able to suppress this dialog ?
You probably have created an HTML page that contains a <form>. The form is used to send data to the HTTP server (that is, the webserver that hosts your site).
The HTTP protocol defines different request types used to send data to the server and to retrieve data from the server. The most used are GET and POST. You must learn about all this if you want to be anything more than a very bad PHP programmer, which is unfortunately (or fortunately, if you are on the hacker side) very common.
Your problem is that Firefox has arrived on the page you are talking about after sending a POST request. If you reload the page, it has to send the same data again in the form of a POST. Due to the conventions on what a POST request should be used for (usually to modify data on a database), the browser asks the user if he is sure about what he wants to do.
There are mainly two options to circumvent this:
Change the form method to GET; or
Use a redirection after the POST.
To use the first method, you could simply add a method="get" parameter to your form tag:
<form action="senddata.php" method="get"> ... </form>
To use the second method, you simply redirect the user after the POST request, using something like
header("Location: blahblahblah")
The most used pattern is the POST-Redirect, that is, the second method I told you about. There are many security implications on using GET to change data on a database (if you are interested on that, and you should be, as every PHP programmer should, read about XSRF).
Submitting a form (sending a POST request) is commonly used to confirm an order on eCommerce sites. Therefore, submitting it twice would submit the order, twice. Therefore browsers, tend to ask for confirmation that a user wants to send the POST request again.
In order to prevent this, you need to make the refresh do a GET request instead of a POST request. To do this, simply redirect to the same page after processing the form.
header("Location: /path/to/self");
This will make it so when the user hits refresh, it will be sending a GET request instead of a POST request, and it won't prompt for confirmation.
To clairify, it goes like this:
Form gets sent via POST (User clicks on form)
Form gets processed
User gets redirected to the same page (via GET)
User now will be refreshing a GET request instead of a POST request.
I guess whenever your form (php, asps, static html etc) contains post information that may either form field infor or other, is sent to the server via firefox, it displays such a message before sending the data again to server. it serves as a security protection from Mozilla developers. I guess it can be disabled via about:config but it is not recommended to so.
Also it is a normal behaviour. It should be like this and have been like this for a fairly long time in firefox.
You may like to have a look here:
http://forums.mozillazine.org/viewtopic.php?f=38&t=682835&st=0&sk=t&sd=a&hilit=Firefox+must+send
alternatively use GET instead of POST to send your data...
Regards
If the form was submitted successfully, answer with the status code 303:
header('Location: http://www.example.com/', TRUE, 303);
This forces the browser to use a GET request for the resulting page. A reload won’t send any POST data, and no pop up is shown.