web-dev-qa-db-fra.com

Comment empêcher CORB de bloquer les demandes de ressources de données qui répondent avec des en-têtes CORS?

Je suis en train de développer une extension Chrome qui effectue des requêtes de certains sites Web vers une API que je contrôle. Jusqu'à Chrome 73, l'extension fonctionnait correctement. Après la mise à niveau vers Chrome 73, j'ai commencé à obtenir l'erreur suivante:

Cross-Origin Read Blocking (CORB) a bloqué la réponse Cross Origin http: // localhost: 3000/api/users/1 avec l'application de type MIME/json

Selon documentation de Chrome sur CORB , CORB bloquera la réponse d'une demande si toutes les conditions suivantes sont remplies:

  1. La ressource est une "ressource de données". Plus précisément, le type de contenu est HTML, XML, JSON

  2. Le serveur répond avec un en-tête X-Content-Type-Options: nosniff, Ou si cet en-tête est omis, Chrome détecte que le type de contenu est un format HTML, XML ou JSON pour inspecter le fichier

  3. CORS n'autorise pas explicitement l'accès à la ressource

De plus, selon "Lessons from Specter and Meltdown" (Google I/O 2018) , il semble qu'il peut être important d'ajouter mode: cors Aux invocations fetch, c'est-à-dire fetch(url, { mode: 'cors' }).

Pour essayer de résoudre ce problème, j'ai apporté les modifications suivantes:

Tout d'abord, j'ai ajouté les en-têtes suivants à toutes les réponses de mon API:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Origin: https://www.example.com

Deuxièmement, j'ai mis à jour mon fetch() invocation sur l'extension pour ressembler à ceci:

fetch(url, { credentials: 'include', mode: 'cors' })

Cependant, ces changements n'ont pas fonctionné. Que puis-je changer pour que ma demande ne soit pas bloquée par CORB?

14
Ceasar Bautista

Sur la base des exemples de "Modifications des demandes d'origine croisée dans Chrome Scripts de contenu d'extension" , j'ai remplacé toutes les invocations de fetch par une nouvelle méthode fetchResource, qui a une API similaire, mais délègue l'appel fetch à la page d'arrière-plan:

// contentScript.js
function fetchResource(input, init) {
  return new Promise((resolve, reject) => {
    chrome.runtime.sendMessage({input, init}, messageResponse => {
      const [response, error] = messageResponse;
      if (response === null) {
        reject(error);
      } else {
        // Use undefined on a 204 - No Content
        const body = response.body ? new Blob([response.body]) : undefined;
        resolve(new Response(body, {
          status: response.status,
          statusText: response.statusText,
        }));
      }
    });
  });
}

// background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  fetch(request.input, request.init).then(function(response) {
    return response.text().then(function(text) {
      sendResponse([{
        body: text,
        status: response.status,
        statusText: response.statusText,
      }, null]);
    });
  }, function(error) {
    sendResponse([null, error]);
  });
  return true;
});

Il s'agit du plus petit ensemble de modifications que j'ai pu apporter à mon application pour résoudre le problème. (Remarque: les extensions et les pages d'arrière-plan ne peuvent passer que des objets sérialisables JSON entre elles, nous ne pouvons donc pas simplement passer l'objet Fetch API Response de la page d'arrière-plan à l'extension.)

Les pages d'arrière-plan ne sont pas affectées par CORS ou CORB, de sorte que le navigateur ne bloque plus les réponses de l'API.

14
Ceasar Bautista

Solution temporaire: désactivez CORB avec le navigateur de commandes d'exécution --disable-features=CrossSiteDocumentBlockingAlways,CrossSiteDocumentBlockingIfIsolating

Exemple de commande d'exécution sous Linux.

Pour Chrome:

chrome %U --disable-features=CrossSiteDocumentBlockingAlways,CrossSiteDocumentBlockingIfIsolating

Pour le chrome:

chromium-browser %U --disable-features=CrossSiteDocumentBlockingAlways,CrossSiteDocumentBlockingIfIsolating

Question similaire.

Source .

1
Epexa

Voir https://www.chromium.org/Home/chromium-security/extension-content-script-fetches

Pour améliorer la sécurité, les récupérations multi-origines seront bientôt interdites à partir des scripts de contenu dans les extensions Chrome. De telles demandes peuvent être effectuées à partir des pages d'arrière-plan des extensions et relayées aux scripts de contenu si nécessaire.

Vous pouvez le faire pour éviter l'origine croisée.

Ancien script de contenu, effectuant une extraction croisée d'origine:

var itemId = 12345;
var url = "https://another-site.com/price-query?itemId=" +
         encodeURIComponent(request.itemId);
fetch(url)
  .then(response => response.text())
  .then(text => parsePrice(text))
  .then(price => ...)
  .catch(error => ...)

Nouveau script de contenu, demandant à sa page d'arrière-plan de récupérer les données à la place:

chrome.runtime.sendMessage(
    {contentScriptQuery: "queryPrice", itemId: 12345},
    price => ...);

Nouvelle page d'arrière-plan d'extension, récupérant à partir d'une URL connue et relayant des données:

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.contentScriptQuery == "queryPrice") {
      var url = "https://another-site.com/price-query?itemId=" +
              encodeURIComponent(request.itemId);
      fetch(url)
          .then(response => response.text())
          .then(text => parsePrice(text))
          .then(price => sendResponse(price))
          .catch(error => ...)
      return true;  // Will respond asynchronously.
    }
  });
0
李方郑