Glutch
Glutch

Reputation: 720

Prevent website to send specific post requests

Is it possible to prevent a specific site (example: facebook.com) to send a specific post request?

Is there any way i can "ban" facebook to post to a specific url?

I'm trying to block the "https://www.messenger.com/ajax/mercury/delivery_receipts.php?dpr=2" request

Upvotes: 1

Views: 2674

Answers (2)

user4639281
user4639281

Reputation:

You can prevent AJAX requests at the client side.

First you need to overwrite XMLHttpRequest.prototype.open. In this function, call the original open function with the supplied arguments. Then store a reference to the send function of this XMLHttpRequest. Finally overwrite the send function of this XMLHttpRequest.

In the new send function, compare the method and post arguments supplied to the open function call. If the it passes the comparison, call the original send function with the original arguments. If it does not pass, do nothing, you have successfully blocked the request.

function blockXHR(compare) {
  const open = XMLHttpRequest.prototype.open;

  XMLHttpRequest.prototype.open = function(method, url) {
    open.apply(this, arguments);

    const send = this.send;

    this.send = function() {
      if(compare(method, url)) {
        return send.apply(this, arguments);
      }
      console.log('blocked request');
    };
  };
}

The rest of the code code in the demo below exists to demonstrate the use of this, and that it does work. For simplicity I have used some features introduced in the ECMAScript 2015 Language Specification, but none of these features are necessary to accomplish this task.

function blockXHR(compare) {
  const open = XMLHttpRequest.prototype.open;
  
  XMLHttpRequest.prototype.open = function(method, url) {
    open.apply(this, arguments);

    const send = this.send;

    this.send = function() {
      if(compare(method, url)) {
        return send.apply(this, arguments);
      }
      console.log('blocked request');
    };
  };
}

const requestFactory = (method, url, callback) => {
  const xhr = new XMLHttpRequest();
  xhr.addEventListener('load', callback);
  xhr.open(method, url);
  xhr.send();
};
const comparisonFactory = (targetMethod, targetURL) => 
  (method, url) => !(method === targetMethod && url === targetURL);
const callback = event => console.log(event.target.status);

blockXHR(comparisonFactory('POST', 'http://placehold.it/1x1'));
requestFactory('POST', 'http://placehold.it/1x1', callback); // blocked request
requestFactory('GET', 'http://placehold.it/1x1', callback); // 200
requestFactory('POST', 'http://placehold.it/1x1?hello', callback); // 200

Upvotes: 1

Quentin
Quentin

Reputation: 943537

You can never prevent a third party from making an HTTP request (well, short of blocking them at the network level before they connect to the HTTP server, and that limits you to detecting the request via IP address (see below)).

You can attempt to detect that third party and handle the request differently (e.g. immediately return a 403 error).

The main ways to detect the third party are:

  • Their IP address (which might change and which might be shared with other people)
  • Their user-agent string (which is unlikely to change unless they are trying to evade your detection, but which might clash with a standard browser user-agent).
  • Their lack of credentials, such as a cookie (which requires you to give those credentials to everybody else before they can access the URL).

In general, however, a GET request to a URL should be harmless. If you are trying to stop them making it, it is likely because the request has side effects (such as deleting something from a database).

If so, then the solution is to require a POST request. The HTTP specification says that GET requests should be safe.

Upvotes: 0

Related Questions