chrome.webRequest.onHeadersReceived.addListener in firefox - firefox

I'm doing an extension for Firefox and I pick up the call to the URL, as I can capture the http request in firefox, when running a call to a URL.
For example in google chrome on the event: chrome.webRequest.onHeadersReceived.addListener (

Use plain XMLHttpRequest, which, when run from some chrome-privileged (system principal) place, allows to access all resources without obeying the same-origin policy, just like the SDK request module does not obey it.
SDK: in a lib/ module get it via
const {XMLHttpRequest} = require("sdk/net/xhr");
XUL overlays/windows, ChromeWorker: There already is a global XMLHttpRequest constructor.
JS code modules, etc: Components.classes["#mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance(Components.interfaces.nsIXMLHttpRequest);
From there you can use onreadystatechange to look for a .readyState of HEADERS_RECEIVED. See the XMLHttpRequest docs.
To get cookies working for users with Deny Third-Party-Cookies you'll need to use forceAllowThirdPartyCookie in the SDK or otherwise:
if (xhr_instance.channel instanceof Components.interfaces.nsIHttpChannelInternal)
xhr_instance.channel.forceAllowThirdPartyCookie = true;

Related

SignalR responses overwriting headers

I've built a simple SignalR hub that lives within a WebAPI service, I've included all the required CORS attributes on both WebAPI and SignalR. My WebAPI endpoints are all working as expected but SignalR isn't.
I've tried all I can think of and all I can find online but nothing works, I already tried this answer, and this other to no solution.
My SignalR extension method looks like this
public static IAppBuilder UseSignalrNotificationService(this IAppBuilder app)
{
var config = new HubConfiguration();
config.Resolver = new HubDependencyResolver();
config.EnableDetailedErrors = true;
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR(config);
return app;
}
And I even tried adding the response headers on all requests using the Web.config but I allways get the same error:
XMLHttpRequest cannot load https://MyApplicationServer/notifications/signalr/negotiate?clientProtocol=1.5&access_token=&connectionData=. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'MyOriginService' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.
After more research and fiddling with the server side of the problem, I ran into this answer and found the error to be with the client side of the request. according to this GitHub issue, the "withCredentials" parameter of the request is always set to 'true'. The solution was to call on the client the start method as follows:
$.connection.hub.start({ withCredentials: false }).done(function () { //... }
Are you changing the request somewhere with some kind of global interceptor? For some reason, the XMLHttpRequest starts with withCredentials:true and this is forbidden when the Access-Control-Allow-Origin is set to *.
What about setting the 'Access-Control-Allow-Origin' to 'http://MyApplicationServer'? It's safer than * and will remove your problem at source.

Template-less Django + AJAX: Does Django's CSRF token get updated during the course of a browsing session?

My current setup is AngularJS + Django 1.5 and I have completely thrown away the use of Django's template engine (ie. the backend is pretty much an API server).
Since I am not using the csrf_token template tag, Django, in turn, does not set and send the csrftoken cookie in response. As instructed by the official docs, the ensure_csrf_cookie() decorator should be used to force the decorated view to send the csrftoken cookie.
I have applied the ensure_csrf_cookie() decorator to the view, which serves the first GET request that my web client calls at bootstrapping. With that, my web client gets a hold of the CSRF token and henceforth is allowed to call unsafe methods (ex. POST) to the server.
The above setup works fine only if the CSRF token remains the same until the browsing session ends.
Question: Does Django's CSRF token get updated during the course of a browsing session? If 'yes', does that mean I would need to apply the ensure_csrf_cookie() decorator to all the views I have?
1) Does Django's CSRF token get updated during the course of a browsing session?
Looks like the CSRF token is unique per session, but it is based in my observations, I have no "official" source. With Angular.js I use the following code without problems:
angular.module('app', ...)
.config(function($httpProvider) {
var cookies = document.cookie.split(';');
var csrftoken = _.find(cookies, function(v) {
return v.trim().indexOf('csrftoken=') == 0;
});
if(csrftoken) {
$httpProvider.defaults.headers.common['X-CSRFToken'] = csrftoken.split('=')[1];
}
})
Since I serve the HTML from Django, by the time Angular bootstraps the cookie is already there.
2) If 'yes', does that mean I would need to apply the ensure_csrf_cookie() decorator to all the views I have?
You can try CORS instead if CSRF. Otto Yiu maintains the django-cors-headers package, which is known to work correctly with REST framework APIs.
Some (untested) ideas to apply ensure_csrf_cookie():
monkey-patch APIView
create a CSRFCookie mixin and add it to your views
apply ensure_csrf_cookie() to your base classes
Giving support to the #Paulo Scardine ideas of applying the ensure_csrf_cookie() (which I consider valid, and useful), I would like to add a new one possible solution to it, if you definitely have to ensure_csrf_cookie() in all your views. You could write a custom middleware, and implement the logic that is there inside the ensure_csrf_cookie. Something like this:
On your app.middleware.py:
from django.middleware.csrf import get_token
class EnsureCsrfCookie(object):
def process_request(self, request):
# Forces process_response to send the cookie
get_token(request)
and of courses on your settings file add the middleware to the MIDDLEWARE_CLASSES:
MIDDLEWARE_CLASSES = (
.,
.,
.,
'app.middleware.EnsureCsrfCookie',
.,
.,
.,
)
It is just one idea more to face this problem. I hope it can be useful for somebody in the future.

Angular JS $http request does not reach the server in ie8

I'm having issues with using $http on ie8. The request does not reach the server, until I hit a refresh. Coming back to the same link still has the same problem until I hit refresh again.
The weird thing is if the web server is on LAN and the request is made to a server in LAN, it works fine. But if the webserver is hosted remotely, it does not work!
Here is the code:
Index.html
{{test}}
Controller
app.controller(
"TestController",
function( $scope, $http) {
var url = '/test/get_data';
$http.get(url).success(function(data) {
$scope.test = data;
});
}
);
I got this error: TypeError: Object doesn't support this property or methodundefined
I prepared a JSFiddle earlier but JSFiddle is broken in ie8 so I don't provide it here.
Unfortunately I don't have a remote server that I can share with you.
Edit
Previously I used an external url which gave me 'Access Denied' error in ie because of Same Origin Policy as mentioned by one answer below. But this was not my original problem. I still have the issue above when request is from the same origin
This is a cross domain request, which is not allowed in ajax because of Same Origin Policy.
There are two solutions for this
1. JSONP: It is a cross browser way to handle cross domain ajax requests using javascript callback mechanism
2. CORS: It is a HTML5 standard, it is implemented by most of the modern browsers except IE
Mongodb lab is not supporting jsonp since it has support for CORS, that is why your request is failing in IE and works in Chrome and other browsers.
As per this post they do not have any plan to support jsonp, so I don't thick there is a way to make this work in IE.
So I found the fix... Hope this helps anyone out there that experience this problem
Angular script needs to be loaded after jQuery. I didn't have this because Yii framework that I use autoloads jQuery and the angular was not included after the jQuery.
All the controller functions need to be at the end of body section (just before the closing )
Updating to angular 1.0.5 seems to fix the problem. The problem occurred in 1.0.4 with all the above tricks. I think is related to fix 791804bd

Cross domain javascript ajax request - status 200 OK but no response

Here is my situation:
Im creating a widget that site admins can embed in their site and the data are stored in my server. So the script basically has to make an ajax request to a php file in my server to update the database. Right? Right :)
The ajax request works excellent when i run it in my local server but it does not work when the php file is on my ONLINE server.
This is the code im using:
var url = "http://www.mydomain.net/ajax_php.php";
var params = "com=ins&id=1&mail=mymail#site.net";
http.async = true;
http.open("POST", url, true);
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
//do my things here
alert( http.responseText );
}
}
http.send(params);
In firebug it shows: http://www.mydomain.net/ajax_php.php 200 OK X 600ms.
When i check the ajax responnseText I always get a Status:0
Now my question is: "Can i do cross-domain ajax requests by default? Might this be a cross-domain ajax problem? Since it works when the requested file resides in my local server but DOESN'T work when the requested file is in another server, im thinking ajax requests to another remote server might be denied? Can you help me clear on this?
Thanks..
Cross-domain requests are not directly allowed. However, there is a commonly-used technique called JSONP that will allow you to avoid this restriction through the use of script tags. Basically, you create a callback function with a known name:
function receiveData(data) {
// ...
}
And then your server wraps JSON data in a function call, like this:
receiveData({"the": "data"});
And you "call" the cross-domain server by adding a script tag to your page. jQuery elegantly wraps all of this up in its ajax function.
Another technique that I've had to use at times is cross-document communication through iframes. You can have one window talk to another, even cross-domain, in a restricted manner through postMessage. Note that only recent browsers have this functionality, so that option is not viable in all cases without resorting to hackery.
You're going to need to have your response sent back to your client via a JSONP call.
What you'll need to do is to have your request for data wrapped in a script tag. Your server will respond with your data wrapped in a function call. By downloading the script as an external resource, your browser will execute the script (just like adding a reference to an external JS file like jQuery) and pass the data to a known JS method. Your JS method will then take the data and do whatever you need to do with it.
Lots of steps involved. Using a library like jQuery provides a lot of support for this.
Hope this helps.

Why does this cross-domain request work in other browsers but not IE9?

I have some Ajax code that is working in Safari, Chrome and Firefox but not in IE9.
The page is on http://foo.com/test.aspx and it's making an AJAX request to a webservice hosted on https://service.foo.com. I thought I wouldn't have any cross-domain issues but given IE9 is blocking it, it appears that I do :(
var tempUrl = "https://service.foo.com/dummy.svc/test?hi=bye";
$.get(tempUrl, "html");
As I mentioned, the code works in the other 3 browsers, just not IE9. (I'm only concerned about IE9, not IE8 or older).
I did some digging and found this article on MSDN that says:
Cross-domain requests require mutual
consent between the Web page and the
server. You can initiate a
cross-domain request in your Web page
by creating an XDomainRequest object
off the window object and opening a
connection to a particular domain. The
browser will request data from the
domain's server by sending an Origin
header with the value of the origin.
It will only complete the connection
if the server responds with an
Access-Control-Allow-Origin header of
either * or the exact URL of the
requesting page. This behavior is part
of the World Wide Web Consortium
(W3C)'s Web Application Working
Group's draft framework on client-side
cross-domain communication that the
XDomainRequest object integrates with.
Before I go down the path of using XDR I wanted to verify with people smarter than me whether this is the right approach or not.
Add Response.AddHeader("Access-Control-Allow-Origin", "*"); to my page
Create condition jscript code that detects IE9 and uses XDR instead of the regular jquery call I'm using with $.get.
Am I totally off or is this the right way to go about this?
(Assuming it's the right way to go, where does the Acecss-Control-Allow-Origin response header go -- on my page at http://foo.com/test.aspx or on the webservice at https://service.foo.com?)
Instead of $.ajax(), use this custom code:
function newpostReq(url,callBack)
{
var xmlhttp;
if (window.XDomainRequest)
{
xmlhttp=new XDomainRequest();
xmlhttp.onload = function(){callBack(xmlhttp.responseText)};
}
else if (window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest();
else
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
callBack(xmlhttp.responseText);
}
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
Note: this works for GET requests.
To adapt it on POST requests change the following lines:
function newpostReq(url,callBack,data)
data is the URL encoded parameters of the post requests such as : key1=value1&key2=value%20two
xmlhttp.open("POST",url,true);
try{xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");}catch(e){}
xmlhttp.send(data);
To summarize, open the connection as POST request (Line 1), set the request header for urlencoded type of the post data (wrap it with try-catch for exceptional browsers) (Line 2), then send the data (Line 3).
i just wrestled with the same problem.
php backend, right mime and yes,
header('Access-Control-Allow-Origin: *');
worked in almost* every browser - except IE9.
seems like jQuery.getJSON doesn't automatically do XDR for ie9 - after creating a service proxy on the same domain, it worked.
* almost - opera acts up too.
edit: okay, opera did have the same problem as ie9. works like a charm now.
note: chrome, safari and the firefoxes (3.6-5) had no problem with the cross domain requests with ACAO:*.
what i don't understand is why a) microsoft uses a different object for cross domain requests and b) why jquery doesn't switch transparently (or at least provide an option to choose).
If this works in the other browsers (which support CORS), then your SVC seems to already be supporting this, but to be sure, use Fiddler2 to see what is going on.
The Access-Control-Allow-Origin header is used on the resource being requested, not on the page requesting it.

Resources