Обойти X-Frame-Options DENY в расширении Chrome?

Я являюсь автором Intab, расширения Chrome, которое позволяет просматривать встроенную ссылку, а не новую вкладку. За кулисами не происходит ничего особенного, это просто iframe, который загружает URL, на который нажал пользователь.

Он отлично работает, за исключением сайтов, которые устанавливают для заголовка X-Frame-Options значение DENY или SAMEORIGIN. Некоторые действительно большие сайты, такие как Google и Facebook, используют его, что делает его немного шатким.

Есть ли способ обойти это? Так как я использую расширение Chrome, есть ли какие-то вещи уровня браузера, к которым я могу получить доступ, которые могут помочь? Ищете любые идеи или помощь!

3 ответа

Решение

Chrome предлагает webRequest API для перехвата и изменения HTTP-запросов. Вы можете удалить X-Frame-Options заголовок, чтобы разрешить встраивание страниц в iframe.

chrome.webRequest.onHeadersReceived.addListener(
    function(info) {
        var headers = info.responseHeaders;
        for (var i=headers.length-1; i>=0; --i) {
            var header = headers[i].name.toLowerCase();
            if (header == 'x-frame-options' || header == 'frame-options') {
                headers.splice(i, 1); // Remove header
            }
        }
        return {responseHeaders: headers};
    },
    {
        urls: [ '*://*/*' ], // Pattern to match all http(s) pages
        types: [ 'sub_frame' ]
    },
    ['blocking', 'responseHeaders']
);

В манифесте необходимо указать webRequest а также webRequestBlocking разрешения, а также шаблоны URL, которые вы собираетесь перехватить.

Пример ManifestV3 с использованием declarativeNetRequest

Давайте воспользуемся новым API declarativeNetRequest для удаления заголовка только тогда, когда iframe встроен в страницы нашего расширения.

manifest.json:

        "permissions": ["declarativeNetRequest"],
  "host_permissions": ["*://*.example.com/"],
  "background": {"service_worker": "bg.js"},

bg.js:

      const iframeHosts = [
  'example.com',
];
chrome.runtime.onInstalled.addListener(() => {
  chrome.declarativeNetRequest.updateDynamicRules({
    removeRuleIds: iframeHosts.map((h, i) => i + 1),
    addRules: iframeHosts.map((h, i) => ({
      id: i + 1,
      condition: {
        domains: [chrome.runtime.id],
        urlFilter: `||${h}/`,
        resourceTypes: ['sub_frame'],
      },
      action: {
        type: 'modifyHeaders',
        responseHeaders: [
          {header: 'X-Frame-Options', operation: 'remove'},
          {header: 'Frame-Options', operation: 'remove'},
        ],
      },
    })),
  });
});

Вы можете попробовать расширение Frame, которое позволяет пользователю сбрасывать заголовки HTTP-ответа X-Frame-Options и Content-Security-Policy, что позволяет создавать страницы в виде фреймов.

Код доступен на гитхабе

Он основан на ManifestV3 и отлично работает с Google и Facebook.

Другие вопросы по тегам