Security of ajax serving php file - javascript

Imagine situation, I've ajax.php file that displays specific information based on ajax request.
How can I block all requests going to ajax.php file except coming via ajax?
I'm looking for something like this in php:
if ($ajax) {
//Do soemthing
}
Will this guarantee that malicious user won't be able to see what ajax.php has to display? Since ajax has same origin policy, request must originate from the same domain, so in theory nobody will be able to call my ajax.php?

There is no way to reliably tell whether a request is an Ajax request or not, ever. Any client side information (like the referer) can be spoofed and you can not trust any of it.
You secure Ajax requests like any other request - usually through a session-based login system that checks whether the requesting client is logged in, and what they are allowed to see.

Other answers already mentioned it: there's no reliable way to determine if a script was called via an AJAX request. But I use this code to detect AJAX request:
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
Keep in mind that it can be spoofed, so don't depend on it.

What am doing to secure our ajax requests - Whenever any user logins at that time generate a token for the user e.g get the micro time and then convert into some hash, then attach this token with that user.

Related

How to avoid "fake" AJAX requests in Chrome extension

I am writing a small Chrome extension, and my question mostly about the algorithms. Suppose, my extension should send some AJAX requests to my server. Is there any way to be sure that this particular AJAX request was received exactly from my extension? I mean, make sure that this is not the user sent this request by falsifying it. I will be grateful for any ideas.
You need to check request origin on your server which must contain your extension ID.
When you send AJAX request from your extension the Origin parameter will be like this
chrome-extension://<extension_id>
Now on server you need to check this origin. Example in php
$extensionID = "YOUR_EXTENSION_ID";
$origin = $_SERVER['HTTP_ORIGIN'];
if (strpos($origin, $extensionID) === false) {
// exit from code
exit();
}
Here is complete anwser how to find origin from request.
Now your server will receive AJAX request only from your extension. If someone copy your code and run from another extension, your server will not handle that request.
Note that this will protect you from falsifying requests from other extensions. User still can open your extension background page and send AJAX request from console.

Preventing spammy XMLHTTP requests to php

I have a site that sends XMLHTTPRequests to a php file that handles the HTTP POST Request and returns data in JSON format. The urls for the post_requests files are public information (since a user can just view the JS code for a page and find the URLs I'm sending HTTP requests to)
I mainly handle HTTP Post Requests in PHP by doing this:
//First verify XMLHTTPRequest, then get the post data
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest')
{
$request = file_get_contents('php://input');
$data = json_decode($request);
//Do stuff with the data
}
Unfortunately, I'm fairly sure that the headers can be spoofed and some devious user or click bot can just spam my post requests, repeatedly querying my database until either my site goes down or they go down fighting.
I'm not sure if their requests will play a HUGE role in the freezing the server with their requests (as 20 requests per second isn't that much). Should I be doing something about this? (especially in the case of a DDOS attack). I've heard of rate-limiting where you record an instance of every time some IP requests data and then trace if they are spammy in nature:
INSERT INTO logs (ip_address, page, date) values ('$ip', '$page', NOW())
//And then every time someone loads the php post request, check to see if they loaded the same one in the past second or 10 seconds
But that means every time there's a request by a normal user, I have to expend resources to log them. Is there a standard or better "practice" (maybe some server configuration?) for preventing or dealing with his concern?
Edit: Just for clarification. I'm referring to some person coding a software (with a cookie or is logged in) that just sends millions of requests per second to all my PHP post request files on my site.
The solution for this is to rate-limit requests, usually per client IP.
Most webservers have modules which can do this, so use one of them - that way your application only receives requests it's suppsed to handle.
nginx: ngx_http_limit_req
Apache: mod_evasive
There are many things you can do:
Use tokens to authenticate request. Save token in session and allow only some amount of requests per token (eg. 20). Also make tokens expire after some amount of time (eg. 5 min). The exact values depend on your site usage patterns. This of course will not stop attacker, as he may refresh the site and grab new token, but it is a small and almost costless aggravation.
Once you have tokens, require captcha after several token refresh requests. Also adjust it to your usage patterns to avoid displaying captcha to regular users.
Adjust your server's firewall rules. Use iptables connlimit and recent modules (see http://ipset.netfilter.org/iptables-extensions.man.html). This will reduce request ratio handled by your http server, so it will be harder to exhaust resources.

How to make a cookieless ajax request?

Is it possible to explicitly make a cookieless request with javascript? I know you can't make a request "emulating" cookies (i.e. submitting data as a cookie value can't be done unless there is an actual cookie set with that value), but this seems to be more acceptable security-wise.
The choices I see are:
You can clear all the client-controlled cookies before making the ajax request (this won't clear server-side only cookies).
You can add an argument to your ajax requests that instructs the server to ignore any cookie values for that particular request.
You can set things up so that the ajax request goes to a server or path that doesn't have access to the cookies of interest so they won't be sent with that request.
If it is one specific cookie value and that value is client-controlled, then you could save that cookie value, clear it, send the ajax request, then restore the cookie value again. Actually, I guess you could do this with all cookie values, but it's simpler to do it with just a few.
As was mentioned in a comment to the question, this is not possible, you do not have any control over this aspect of the browser. The only way I can think to get this to work is to set the PATH of your cookies to a specific directory in your domain (e.g. host.domain.com/myApp), and then have your ajax request be to a directory that is not a child of the directory of the PATH you set for your cookies (e.g. host.domain.com/ajaxDirectory).
A common practice to reduce request size is to have resources on a different sub-domain. This way most cookies won't be sent, but obviously that isn't an option for AJAX (unless you're using JSONP).
this seems to be more acceptable security-wise
Just ignore the cookie that are unused in the server side, or first do a request to the logout service. Another alternative is to code your server so you can override the data in the cookie with, say form encoded data in post body or request header.

Make REST call in JavaScript without using JSON?

(extremely ignorant question, I freely admit)
I have a simple web page with a button and a label. When I click the button, I want to make a REST call to an entirely different domain (cross-domain, I know that much) and display the results (HTML) in the label.
With other APIs, I've played around with using JSON/P and adding a element on the fly, but this particular API doesn't support JSON so I'm not sure how to go about successfully getting through.
The code I have is:
function getESVData() {
$.get('http://www.esvapi.org/v2/rest/passageQuery?key=IP&passage=John+1', function (data) {
$('#bibleText').html(data);
app.showNotification("Note:", "Load performed.");
});
}
I get an "Access denied." Is there anyway to make this call successfully without JSON?
First off, JSON and JSONP are not the same. JSON is a way of representing information, and JSONP is a hack around the same-origin policy. JSONP works by requesting information from another domain, and that domain returns a script which calls a function (with the name you provided) with the information. You are indeed executing a script on your site that another domain gave to you, so you should trust this other domain.
Now when trying to make cross domain requests you basically have 3 options:
Use JSONP. This has limitations, including the fact that it only works for GET requests, and the server you are sending the request to has to support it.
Make a Cross Origin Resource Sharing (CORS) request. This also must be supported by the server you are sending the request to.
Set up a proxy on your own server. In this situation you set an endpoint on your site that simply relays requests. ie you request the information from your server, your server gets it from the other server and returns it to you.
For your situation, it the other server doesn't have support for other options, it seems like you will have to go with options 3.

How to POST data to an HTTP page from an HTTPS page

I know this is a long shot, but I figured I'd ask the question anyway.
I have an HTTPS page and am dynamically creating a form. I want to POST the form to an HTTP page. Is this possible without the browser popping up a warning? When I do this on IE8, I get the following message:
Do you want to view only the webpage content that was delivered securely?
Essentially, I'm asking about the inverse of question 1554237.
Sadly, I know of absolutely no way to not get warned when posting from HTTPS to HTTP. If you serve the form securely, the browser expects to submit the data securely as well. It would surprise the user if anything else was possible.
Nope, can't be done. Our good friend IE will always pop up that warning.
There is a way to do this if you write a back-end service of your own. So lets say you want to post an HTTP request to s1 using your front-end service fs1.
If you use Spring, you can use an ajax call from fs1 to a 'uri' that is recognized by your spring back-end, say bs1. Now, the service bs1 can make the call to the s1.
Pictorial representation here: http://i.stack.imgur.com/2lTxL.png
code:
$.ajax
({
type: "POST",
uri:/json/<methodName>
data: $('#Form').serialize(),
success: function(response)
{
//handle success here
},
error: function (errorResponse)
{
//handle failure here
}
})
You can solve this by either acting as a proxy for the form destination yourself (i.e. let the form submit to your server which in turn fires a normal HTTP request and returns the response), or to let access the page with the form by HTTP only.
If you don't need to actually redirect to the insecure page, you can provide a web service (authenticated) that fires off the request for you and returns the data.
For example:
From the authenticated page, you call doInsecure.action which you create as a web service over https. doInsecure.action then makes a manual POST request to the insecure page and outputs the response data.
You should be able to do this with the opensource project Forge, but it sounds like overkill. The Forge project provides a JavaScript interface (and XmlHttpRequest wrapper) that can do cross-domain requests. The underlying implementation uses Flash to enable cross-domain (including http <=> https) communication.
http://github.com/digitalbazaar/forge/blob/master/README
So you would load the Forge JavaScript and swf from your server over https and then do a Forge-based XmlHttpRequest over http to do the POST. This would save you from having to do any proxy work on the server, but again, it may be more work than just supporting the POST over https. Also, the assumption here is that there's nothing confidential in the form that is being posted.

Categories

Resources