Як замінити параметри X-Frame для контролера або дії в Rails 4


88

Здається, Rails 4 встановлює значення за замовчуванням SAMEORIGINдля X-Frame-Optionsзаголовка відповіді HTTP. Це чудово для безпеки, але це не дозволяє частинам вашої програми бути доступними в iframeіншому домені.

Ви можете перевизначити X-Frame-Optionsглобальне значення за допомогою config.action_dispatch.default_headersналаштування:

config.action_dispatch.default_headers['X-Frame-Options'] = "ALLOW-FROM https://apps.facebook.com"

Але як це замінити лише для одного контролера чи дії?

Відповіді:


137

Якщо ви хочете повністю видалити заголовок, ви можете створити after_actionфільтр:

class FilesController < ApplicationController
  after_action :allow_iframe, only: :embed

  def embed
  end

private

  def allow_iframe
    response.headers.except! 'X-Frame-Options'
  end
end

Або, звичайно, ви можете кодувати, after_actionщоб встановити значення на щось інше:

class FacebookController < ApplicationController
  after_action :allow_facebook_iframe

private

  def allow_facebook_iframe
    response.headers['X-Frame-Options'] = 'ALLOW-FROM https://apps.facebook.com'
  end
end

Зверніть увагу, що вам потрібно очистити кеш у певних браузерах (Chrome для мене) під час налагодження.


Як би ви змусили це працювати на redirect_to? (Я намагаюся зараз із моїм додатком Angular, і він не працює)
kittyminky

Я вважаю, що як дія, що містить, так redirect_toі дія, на яку він перенаправляє, це потрібно буде застосувати. Ви отримуєте конкретну помилку? Звучить як гарне нове запитання щодо Stack Overflow!
Кріс Пітерс,

Я зрозумів, що мав до того, after_action як його було перенаправлено на остаточну дію контролера, яка перенаправляє на Angularмаршрути. Дякую!
kittyminky

Не потрібно робити це в after_action, хоча це зручно робити, наприклад, там, Frontend::BaseControllerде це стосується всього інтерфейсу. Ви також можете бігти response.headers.except! ...в рамках дії.
коденер

2
На даний момент не працює в Chrome. Помилка консолі: "Неправильний заголовок" X-Frame-Options ", який трапився під час завантаження" дочірнього ":" ALLOW-FROM батьківський "не є розпізнаною директивою. Заголовок буде проігноровано." Позначений як не виправлений у Chromium, з альтернативою: "'фрейм-предки' постачаються як у Chrome, так і у Firefox, і це правильний спосіб підтримати цю функціональність". bugs.chromium.org/p/chromium/issues/detail?id=129139
richardkmiller

6

Я просто хотів включити тут оновлену відповідь для кожного, хто знайде це посилання, намагаючись з’ясувати, як дозволити вбудувати вашу програму Rails в I-Frame та зіткнутися з проблемами.

На момент написання цього видання, 28 травня 2020 року, зміни X-Frame-Options, мабуть, не найкраще рішення вашої проблеми. Параметр "ALLOW-FROM" повністю заборонений усіма основними браузерами.

Сучасне рішення полягає у впровадженні політики захисту вмісту та встановленні політики 'frame_ancestors'. Ключ 'frame_ancestors' визначає, які домени можуть вбудовувати вашу програму як iframe. В даний час він підтримується основними браузерами і замінює ваші параметри X-Frame. Це дозволить вам запобігти Clickjacking (який X-Frame-Options спочатку мав допомогти, перш ніж він в основному застарів), і заблокувати ваш додаток у сучасному середовищі.

Ви можете налаштувати Політику безпеки вмісту за допомогою Rails 5.2 в ініціалізаторі (приклад нижче), а для Rails <5.2 ви можете використовувати такий камінь, як самоцвіт Secure Headers: https://github.com/github/secure_headers

Ви також можете замінити специфікації політики на основі контролера / дії, якщо хочете.

Політика щодо вмісту - безпека чудово підходить для вдосконалених засобів захисту. Перегляньте всі речі, які ви можете налаштувати в документації Rails: https://edgeguides.rubyonrails.org/security.html

Приклад Rails 5.2 для політики безпеки вмісту:

# config/initializers/content_security_policy.rb    
    Rails.application.config.content_security_policy do |policy|
      policy.frame_ancestors :self, 'some_website_that_embeds_your_app.com'
    end

Приклад специфічної зміни контролера до політики:

# Override policy inline
class PostsController < ApplicationController
  content_security_policy do |p|
    p.frame_ancestors :self, 'some_other_website_that_can_embed_posts.com'
  end
end

Можна також використовувати p.frame_ancestors :self, -> { company&.allowed_domain || 'none' }
лямбду

0

Для Rails 5+ використовуйте response.set_header('X-Frame-Options', 'ALLOW-FROM https://apps.facebook.com')замість цього. Або якщо ALLOW-FROMце не працює, і вам потрібне швидке виправлення, ви можете встановити це значенняALLOWALL

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.