Jak zastąpić opcje X-Frame dla kontrolera lub akcji w Railsach 4

88

4 Pojawi Szyny ustawić domyślną wartość SAMEORIGINdla X-Frame-Optionsnagłówka odpowiedzi HTTP. Jest to świetne ze względów bezpieczeństwa, ale nie pozwala na udostępnianie części aplikacji w iframeinnej domenie.

Możesz nadpisać wartość X-Frame-Optionsglobalną, używając config.action_dispatch.default_headersustawienia:

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

Ale jak zastąpić to dla pojedynczego kontrolera lub akcji?

Chris Peters
źródło

Odpowiedzi:

137

Jeśli chcesz całkowicie usunąć nagłówek, możesz utworzyć after_actionfiltr:

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

  def embed
  end

private

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

Lub, oczywiście, możesz zakodować, after_actionaby ustawić wartość na inną:

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

Pamiętaj, że musisz wyczyścić pamięć podręczną w niektórych przeglądarkach (Chrome dla mnie) podczas debugowania tego.

Chris Peters
źródło
Jak sprawiłbyś, żeby to działało na redirect_to? (Próbuję teraz z moją aplikacją Angular i nie działa)
kittyminky
Zakładam, że zarówno akcja zawierająca, jak redirect_toi akcja, do której przekierowuje, wymagałyby zastosowania tego. Czy otrzymujesz konkretny błąd? Brzmi jak dobre nowe pytanie na temat przepełnienia stosu!
Chris Peters
Zdałem sobie sprawę, że miałem after_action przed przekierowaniem do ostatecznej akcji kontrolera, która przekierowuje do Angulartras. Dziękuję Ci!
kittyminky
Nie jest to wymagane w programie after_action, chociaż jest to przydatne np. W Frontend::BaseControllerprzypadku, gdy dotyczy to całej nakładki. Równie dobrze możesz biec response.headers.except! ...w ramach akcji.
kodener
2
Na razie nie działa w Chrome. Błąd konsoli to „Napotkano nieprawidłowy nagłówek„ X-Frame-Options ”podczas ładowania elementu„ child ”:„ ALLOW-FROM parent ”nie jest rozpoznaną dyrektywą. Nagłówek zostanie zignorowany." Oznaczone jako nie można naprawić w Chromium, z alternatywą: „„ frame-ancestors ”jest dostępny zarówno w przeglądarce Chrome, jak i Firefox i jest właściwym sposobem obsługi tej funkcji”. bugs.chromium.org/p/chromium/issues/detail?id=129139
richardkmiller
5

Chciałem tylko dołączyć zaktualizowaną odpowiedź dla każdego, kto znajdzie ten link, próbując dowiedzieć się, jak zezwolić aplikacji Rails na osadzenie w I-Frame i napotkanie problemów.

W chwili pisania tego, 28 maja 2020 r., Zmiany opcji X-Frame prawdopodobnie nie są najlepszym rozwiązaniem twojego problemu. Opcja „ZEZWÓL-OD” została całkowicie zabroniona przez wszystkie główne przeglądarki.

Nowoczesne rozwiązanie polega na zaimplementowaniu Content-Security-Policy i ustawieniu polityki 'frame_ancestors'. Klucz „frame_ancestors” wskazuje, które domeny mogą osadzać Twoją aplikację jako element iframe. Obecnie jest obsługiwany przez główne przeglądarki i zastępuje X-Frame-Options. Pozwoli to zapobiec przechodzeniu przez Clickjacking (w którym X-Frame-Options miał pomóc, zanim w dużej mierze stał się przestarzały) i zablokować aplikację w nowoczesnym środowisku.

Możesz ustawić Content-Security-Policy z Railsami 5.2 w inicjatorze (przykład poniżej), a dla Rails <5.2 możesz użyć klejnotu takiego jak klejnot Secure Headers: https://github.com/github/secure_headers

Jeśli chcesz, możesz również zastąpić specyfikacje zasad na podstawie kontrolera / akcji.

Zasady bezpieczeństwa zawartości doskonale nadają się do zaawansowanych zabezpieczeń. Sprawdź wszystkie rzeczy, które możesz skonfigurować w dokumentacji Rails: https://edgeguides.rubyonrails.org/security.html

Przykład Rails 5.2 dla Content-Security-Policy:

# 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

Przykład zmiany polityki specyficznej dla kontrolera:

# 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
armont_development
źródło
Można również użyć lambdy dla wartości dynamicznych:p.frame_ancestors :self, -> { company&.allowed_domain || 'none' }
Sharagoz
0

W przypadku Rails 5+ użyj response.set_header('X-Frame-Options', 'ALLOW-FROM https://apps.facebook.com')zamiast tego. Lub jeśli ALLOW-FROMnie działa i potrzebujesz szybkiej naprawy, możesz ustawićALLOWALL

camilo.forero
źródło