/dev/posts/

IP address spoofing in order to watch South Park

Published:

Updated:

Trying to bring back some old IP spoofing Firefox extension for watching South Park episodes.

Years ago, I was trying to watch the South Park episodes on the official website. While all the episodes were seemingly available for free on the website, they were sadly not available from a French IP address. So I wrote a Firefox extension which would “spoof” a random US IP address. The extension was sending a X-Forwarded-For HTTP header with an US IP address on all requests for www.southparkstudios.com, media.mtvnservices.com. At that time these servers were happily trusting the IP address in the HTTP header and would grant you access to the episodes 😀.

// Fake US IP address
// taken from https://developer.mozilla.org/en/Setting_HTTP_request_headers

function rand(min, max) {
  var range = max - min;
  return Math.floor((range+1)*Math.random()) + min;
}

var ipSpoofer = {
  ip: "199."+rand(236,240)+"."+rand(0,255)+"."+rand(1,254),
  started: false,
  checkSpoofability : function(httpChannel) {
    return true;
    var host = httpChannel.originalURI.host;
    return host == "www.southparkstudios.com" || host == "media.mtvnservices.com";
  },
  observe: function(subject, topic, data) {
    if (topic == "http-on-modify-request") {
      var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
      if (this.checkSpoofability(httpChannel)) {
        httpChannel.setRequestHeader("X-Forwarded-For", this.ip, false);
      }
    }
  },
  chooseIp : function() {
	  this.ip = "199."+rand(236,240)+"."+rand(0,255)+"."+rand(1,254);
  },
  start: function() {
  	if (!this.started){
  	  if (!this.ip) {
  		  this.chooseIp();
  	  }
  	  Components.classes["@mozilla.org/observer-service;1"].
  		getService(Components.interfaces.nsIObserverService).
  		addObserver(this, "http-on-modify-request", false);
  	  this.started = true;
  	}
  },
  stop: function() {
  	if (this.started)  {
  	  Components.classes["@mozilla.org/observer-service;1"].
  		getService(Components.interfaces.nsIObserverService).
  		removeObserver(this, "http-on-modify-request");
  	  this.started = false;
  	}
  }
};

function startup(data,reason) {
  ipSpoofer.start();
}

function shutdown(data,reason) {
  ipSpooder.stop();
}

The old-Firefox extensions do not work anymore on newest versions of Firefox, with the new extensions system. I rewrote it in order to check if that old trick was still working these days.

function rand(min, max) {
  const range = max - min;
  return Math.floor((range+1)*Math.random()) + min;
}

const ip = "199." + rand(236,240) + "." + rand(0,255) + "."+rand(1,254);

function rewriteHeaders(req) {
  const url = new URL(req.url)
  const headers = Array.from(req.requestHeaders)
  headers.push({
    "name": "X-Forwarded-For",
    "value": ip
  });
  headers.push({
    "name": "Forwarded",
    "value": "by=127.0.0.1; for=" + ip + "; host=" + url.host+ "; proto=" + (url.protocol.replace(":", "")),
  });
  return {requestHeaders: headers};
}

browser.webRequest.onBeforeSendHeaders.addListener(
  rewriteHeaders,
  {urls: ["<all_urls>"]},
  ["blocking", "requestHeaders"]
);

Unsurprisingly, the servers do not blindly trust those HTTP headers anymore.

References