Security Error when trying to load content from resource in a Firefox Addon (SDK)

后端 未结 4 550
-上瘾入骨i
-上瘾入骨i 2020-12-18 12:14

I am creating a firefox addon using the SDK. My goal is simple, to intercept a specific iframe and load my own HTML page (packaged as a resource with my addon) instead of t

相关标签:
4条回答
  • 2020-12-18 12:32

    posting my trials here so it can help all:

    trail 1 failed - created chrome.manifest file with contents content kaboom-data resources/kaboom/data/ contentaccessible=yes

    var myuri = Services.io.newURI('chrome://kaboom-data/content/pages/test.html', undefined, undefined);
    httpChannel.redirectTo(myuri);
    

    Error Thrown

    Security Error: Content at http://digg.com/tools/diggthis/confirm? may not load or link to jar:file:///C:/Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/jid1-g4RtC8vdvPagpQ@jetpack.xpi!/resources/kaboom/data/pages/test.html.

    trial 2 failed - created resource in bootstrap.js

    alias.spec = file:///C:/Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/jid1-g4RtC8vdvPagpQ@jetpack.xpi

    alias updated to spec: jar:file:///C:/Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/jid1-g4RtC8vdvPagpQ@jetpack.xpi!/

       let resource = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
      let alias = Services.io.newFileURI(data.installPath);
      Cu.reportError('alias.spec = ' + alias.spec);
      if (!data.installPath.isDirectory()) {
        alias = Services.io.newURI("jar:" + alias.spec + "!/", null, null);
        Cu.reportError('alias updated to spec: ' + alias.spec);
      }
      resource.setSubstitution("kaboom_data", alias);
    

    ...

    var myuri = Services.io.newURI('resource://kaboom_data/resources/kaboom/data/pages/test.html', undefined, undefined);
    httpChannel.redirectTo(myuri);
    

    Error Thrown

    Security Error: Content at http://digg.com/tools/diggthis/confirm? may not load or link to jar:file:///C:/Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/jid1-g4RtC8vdvPagpQ@jetpack.xpi!/resources/kaboom/data/pages/test.html.

    CONCLUSION in both trials above it was the weirdest thing, it wouldnt show the resource or chrome path in the security error thrown but it would give the full jar path. Leading me to believe that this has something to do with redirectTo function.

    The solution that did work was your solution of

    var gBrowser = utils.getMostRecentBrowserWindow().gBrowser;
    var domWin = httpChannel.notificationCallbacks.getInterface(Ci.nsIDOMWindow);
    var browser = gBrowser.getBrowserForDocument(domWin.document);
    
    //redirect
    browser.loadURI(self.data.url('pages/test.html'));
    

    however I changed this to use loadContext instead of this method because it is the recommended way. also gBrowser to getMostRecentBrowserWindow will fail if the url load is slow and in that time the user swithces to another tab or window

    I also changed to use Services.jsm as you had imported Cu anyways. Using Services.jsm is super fast not even blink fast. Its just a pointer.

    Im still working on trying to the redirectTo method working its really bothering me. The changes I made are to my local copy.

    0 讨论(0)
  • 2020-12-18 12:47

    Have you considered turning your local HTML file into a data URL and loading that?

    0 讨论(0)
  • 2020-12-18 12:53

    actually man i was really over thinking this.

    its already solved when I changed to using loadContext. Now when you get loadContext you get the contentWindow of whatever browser element (tab browser, or frame or iframe) and then just abort the http request like you are doing and then loadContext.associatedWindow.document.location = self.data('pages/tests.html');

    done

    ill paste the code here removing all the private stuff. you might need the chrome.manifest ill test it out and paste the code back here

    Cu.import('resource://gre/modules/Services.jsm');
    
    var httpRequestObserver = {
        observe: function (subject, topic, data) {
            var httpChannel, requestURL;
    
            if (topic == "http-on-modify-request") {
                httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
                requestURL = httpChannel.URI.spec;
    
                var newRequestURL, i;
    
                if (/someurl/.test(requestURL)) {
                    var goodies = loadContextGoodies(httpChannel);
                    if (goodies) {
                        httpChannel.cancel(Cr.NS_BINDING_ABORTED);
                        goodies.contentWindow.location = self.data.url('pages/test.html');
                    } else {
                        //dont do anything as there is no contentWindow associated with the httpChannel, liekly a google ad is loading or some ajax call or something, so this is not an error
                    }
                }
    
                return;
            }
        }
    };
    Services.obs.addObserver(httpRequestObserver, "http-on-modify-request", false);
    
    
    
    
    
    //this function gets the contentWindow and other good stuff from loadContext of httpChannel
    function loadContextGoodies(httpChannel) {
        //httpChannel must be the subject of http-on-modify-request QI'ed to nsiHTTPChannel as is done on line 8 "httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);"
        //start loadContext stuff
        var loadContext;
        try {
            var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
            //var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //not to be done anymore because: https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //instead do the loadContext stuff below
            try {
                loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
            } catch (ex) {
                try {
                    loadContext = subject.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
                } catch (ex2) {}
            }
        } catch (ex0) {}
    
        if (!loadContext) {
            //no load context so dont do anything although you can run this, which is your old code
            //this probably means that its loading an ajax call or like a google ad thing
            return null;
        } else {
            var contentWindow = loadContext.associatedWindow;
            if (!contentWindow) {
                //this channel does not have a window, its probably loading a resource
                //this probably means that its loading an ajax call or like a google ad thing
                return null;
            } else {
                var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
                    .getInterface(Ci.nsIWebNavigation)
                    .QueryInterface(Ci.nsIDocShellTreeItem)
                    .rootTreeItem
                    .QueryInterface(Ci.nsIInterfaceRequestor)
                    .getInterface(Ci.nsIDOMWindow);
                var gBrowser = aDOMWindow.gBrowser;
                var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //this is the clickable tab xul element, the one found in the tab strip of the firefox window, aTab.linkedBrowser is same as browser var above //can stylize tab like aTab.style.backgroundColor = 'blue'; //can stylize the tab like aTab.style.fontColor = 'red';
                var browser = aTab.linkedBrowser; //this is the browser within the tab //this is where the example in the previous section ends
                return {
                    aDOMWindow: aDOMWindow,
                    gBrowser: gBrowser,
                    aTab: aTab,
                    browser: browser,
                    contentWindow: contentWindow
                };
            }
        }
        //end loadContext stuff
    }
    

    NOTE: Now try this first, I didn't test it yet, if you get a security error when it tries to redirect then create a chrome.manifest file and put it in the root directory. If it throws a security error than you definitely need a chrome.manifest file and that will without question fix it up. I'll test this myself later tonight when I get some time.

    The chrome.manifest should look like this:

    content kaboom-data ./resources/kaboom/data/ contentaccessible=yes
    

    Then in the code way above change the redirect line from goodies.contentWindow.location = self.data.url('pages/test.html'); to goodies.contentWindow.location = 'chrome://kaboom-data/pages/test.html');.

    0 讨论(0)
  • 2020-12-18 12:57

    see this addon here: https://addons.mozilla.org/en-US/firefox/addon/ghforkable/?src=search

    in the chrome.manifest file we set the contentaccessible parameter to yes

    you dont need sdk for this addon. its so simple, just ocpy paste that into a bootstrap skeleton as seen here:

    Bootstrap With Some Features, Like chrome.manifest which you will need

    Bootstrap Ultra Basic

    if you want to really do a redirect of a page to your site, maybe you want to make a custom about page? if you would like ill throw togather a demo for you on making a custom about page. you can see a bit hard to understand demo here

    0 讨论(0)
提交回复
热议问题