Search code examples
javascriptfirefoxfirefox-addonhttp-posttamper-data

Firefox - Intercept/Modify post data when some variable match some pattern


I would like to know if it is possible to intercept and modify a post data when the url and some of the variables meet some pattern.

for example:

let the login url be: http://www.someonlineprofiles.com

let the post data be:

email: "[email protected]"
pass: "mypass"
theme: "skyblue"

I would like that if:

url = "http://www.someonlineprofiles.com/ajax/login_action_url" and

email = "[email protected]"

then theme value be unconditionally changed to: "hotdesert"

Is it possible to create a Firefox add-on for that?, are add-ons powerful enough for that?

I found this link: modify the post data of a request in firefox extension

Thanks in advance!

[ADDED INFORMATION]

I don't know if it is interesting to know the version of my Firefox: 35.0.1


Solution

  • Your question borders on being too broad, so I will give only an overview on how to do this, but not a copy-paste-ready solution, which would take a while to create, and would also deny you a learning experience.

    Observers

    First of all, it is possible for add-ons to observe and manipulate HTTP(S) requests before the browser sends the request, you just need to implement and register what is called a http observer.

    const {classes: Cc, instances: Ci, utils: Cu} = Components;
    Cu.import("resource://gre/modules/Services.jsm"); // for Services
    
    var httpRequestObserver = {
      observe: function(channel, topic, data) {
        if (topic != "http-on-modify-request") {
          return;
        }
        if (!(channel instanceof Ci.nsIHttpChannel)) {
          return; // Not actually a http channel
        }
        // See nsIChannel, nsIHttpChannel and nsIURI/nsIURL
        if (channel.URI.host != "www.someonlineprofiles.com") {
          return;
        }
        doSomething(channel);
      },
    
      register: function() {
        Services.obs.addObserver(this, "http-on-modify-request", false);
      },
    
      unregister: function() {
        Services.obs.removeObserver(this, "http-on-modify-request");
      }
    };
    
    httpObserver.register();
    // When your add-on is shut down, don't forget to call httpObserver.unregister();
    

    Do only register the http observer once in your add-on:

    • If you're using the SDK, then put it into main.js or a dedicated module. You'll also need to rewrite the code a bit and replace the const .. = Components line with a require("chrome").
    • If you're writing a XUL overlay add-on, put it into a code module.

    Rewriting post data

    We still need to implement doSomething() and actually rewrite the post data. An http channel usually implements the nsIUploadStream interface, and the upload stream is where the current post data is, if any. It also has a setUploadStream() method, which you can use to replace the upload stream entirely.

    function doSomething(channel) {
      if (!(channel instanceof Ci.nsIUploadStream)) {
        return;
      }
      // construct new post data
       channel.setUploadStream(newStream);
    }
    

    Constructing the new post data would be a matter of your actual requirements. I provided a working example in another answer on how you could do it.

    If you need to fetch some data from the old upload stream, you'll need to decode the existing channel.uploadStream as multipart/form-data yourself. I suggest you check TamperData and similar add-ons on how they do things there.