How to avoid "fake" AJAX requests in Chrome extension - javascript

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.

Related

Chrome extension - how to get response of POST request user invoked from a webpage?

I am trying to create a chrome extension that navigates to a webpage, lets the user click a button on the webpage that sends an asynchronous post request, and to read that response and use it in the extension.
Everything that I am finding from my research is telling me to create the request in the extension itself, which I do not want to do, because I need the web page to make the request itself.
Is there a way to listen to a post request on the page itself on my background script?
You can use chrome.webRequest and onBeforeRequest to fire when a request is about to occur chrome.webRequest.onBeforeRequest.addListener(function callback). Parameters contains the HTTP request data. You also need to supply an extraInfoSpec of requestBody to the listener.
Below is a sample code snippet how to use onBeforeRequest:
const WEB_REQUEST = chrome.webRequest;
WEB_REQUEST.onBeforeRequest.addListener(
function(details) {
if(details.method == "POST")
console.log(JSON.stringify(details));
},
);
For more information regarding POST request, try to read the Chrome Extensions developer guide: https://developer.chrome.com/extensions/getstarted

Security of ajax serving php file

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.

AJAX catch difference between «failed» and «canceled» sending request to another domain

I'm making ajax request to server on another domain but I don't actially need its response, just to know that it got my request.
When everything is ok, in Chrome Developer Tools (Header status) it says «canceled» and console writes «XMLHttpRequest cannot load» but server gets my requests.
When server is down then header status is not a number but just «failed».
Trying to catch this critical difference on JS I get XHR status 0 in both cases.
I'm making ajax request to server on another domain
You can't make an ajax request to a different domain, due to same-origin policy. You want to look at JSONP, which essentially writes out a <script> tag for a remote URL.
What is JSONP all about?
Detecting success/error with JSONP calls is tricky, it doesn't work like typical ajax calls at all. Ideally you want the remote server to call a callback function on your page, as the above link describes.
If you don't control the other domain, you can attempt to detect errors by using a timeout. Here is a post discussing the jQuery timeout argument for this, though you could certainly implement your own timeout with raw javascript as well.

Difference between localhost and IP address in Ajax request sending

I have a strange problem with native Ajax request invoking.
I am creating the Ajax object and sending the request like follows:
var xmlHttpObj = new XMLHttpRequest();
....
xmlHttpObj.open("GET","http://192.168.16.254:8080/ajax/demoExample.html",true);
xmlHttpObj.send();
When I access the servlet with the URL something like http://localhost:8080/ajax...,
then I am not able to get the response in the client side. But I can see the response in the server side.
Pretty similar way I invoked the request with
xmlHttpObj.open("GET","http://localhost:8080/ajax/demoExample.html",true);
and my URL is http://192.168.16.254:8080/ajax..., then also I am not able to see the response in my client side.
I know the best way to fix the problem.
I can invoke the request with
xmlHttpObj.open("GET","../ajax/demoExample.html",true);
xmlHttpObj.send();
then I don't have any problem with either localhost or IP address.
But still I think why is the difference between localhost and IP address in ajax requesting.
It's more of a security feature than a problem :
The same origin policy prevents a
document or script loaded from one
origin from getting or setting
properties of a document from another
origin.
localhost and 192.168.16.254 are considered different origins. The same goes for two hostnames that point to the same address as they could (and probably will) point to a different site/application on the same server. AFAIK the only way around this is to use iframe for content or JSONP for json. Although in your case relative URLs is the way to go.

Update client status to server on "onbeforeunload" event

I have a flash application that needs to send a http request to the server which will disconnect the existing session immediately. I have a tried a few options but none is reliable.
Option #1: On "onbeforeunload" event send a http request from inside the flash applications. Fallacy: This does not work because as soon as the browser is closed the flash player unloads the app and hence the communication breaks.
Option #2: On "onbeforeunload" event send a http request using XMLHTTPRequest in ajax. This works fine in IE but doesnt work in Firefox. When i debugged the http req in httpfox it threw "NS_BINDING_ABORTED" error which i think means that request was cancelled due to page unload.
Note that if i use an alert box, the requests are getting sent in both the options. But i cant use alert boxes. Is there any other way to do so ? or maybe kill the alert box after a timeout ?
It should not be the client's responsibility to tell the server it is disconnecting. You can make the client ping the server regularly to tell it it is still alive, or you could open an never-ending http request (comet-style), and fire the event when the tcp connection is broken.
In PHP it would look somehthing like this: (Not tested)
<?php
// Run script until aborted.
ignore_user_abort(true);
set_time_limit(0);
while(connection_status() == CONNECTION_NORMAL) {
sleep(1);
}
// The connection was lost, so do something.
onLostConnection();
?>
Anyway what was happening was that i was sending a crossdomain xmlhttprequest which is not allowed. see here, http://developer.yahoo.com/javascript/howto-proxy.html . I just fixed the urls and it worked in firefox as well.

Categories

Resources