Come sostituire le opzioni X-Frame per un controller o un'azione in Rails 4


88

Rails 4 sembra impostare un valore predefinito SAMEORIGINper l' X-Frame-Optionsintestazione della risposta HTTP. Questo è ottimo per la sicurezza, ma non consente la disponibilità di parti della tua app in un iframedominio diverso.

Puoi sovrascrivere il valore di X-Frame-Optionsglobalmente utilizzando l' config.action_dispatch.default_headersimpostazione:

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

Ma come sovrascriverlo per un solo controller o azione?

Risposte:


137

Se desideri rimuovere completamente l'intestazione, puoi creare un after_actionfiltro:

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

  def embed
  end

private

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

Oppure, ovviamente, puoi codificare after_actionper impostare il valore su qualcosa di diverso:

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

Tieni presente che devi svuotare la cache in alcuni browser (Chrome per me) durante il debug.


Come faresti a farlo funzionare su un redirect_to? (Sto provando in questo momento con la mia app Angular e non funziona)
kittyminky,

Presumo che sia l'azione contenente il redirect_toche l'azione a cui reindirizza avrebbero bisogno di questo per essere applicato. Stai ricevendo un errore particolare? Sembra una buona nuova domanda su Stack Overflow!
Chris Peters

Mi sono reso conto di averlo after_action prima che fosse reindirizzato all'azione del controller finale che reindirizza alle Angularrotte. Grazie!
kittyminky

Non è necessario farlo in un after_action, sebbene sia utile farlo, ad esempio in a, Frontend::BaseControllerdove si applica all'intero frontend. Puoi anche correre response.headers.except! ...all'interno di un'azione.
codener

2
A partire da ora, non funziona in Chrome. L'errore della console è "Rilevata intestazione" X-Frame-Options "non valida durante il caricamento di" figlio ":" ALLOW-FROM genitore "non è una direttiva riconosciuta. L'intestazione verrà ignorata." Contrassegnato come non risolvibile in Chromium, con un'alternativa: "'frame-ancestors' è disponibile sia in Chrome che in Firefox ed è il modo giusto per supportare questa funzionalità." bugs.chromium.org/p/chromium/issues/detail?id=129139
richardkmiller

5

Volevo solo includere una risposta aggiornata qui per chiunque trovi questo collegamento quando cerca di capire come consentire alla tua app Rails di essere incorporata in un I-Frame e incorrere in problemi.

Al momento della stesura di questo, 28 maggio 2020, le modifiche alle opzioni X-Frame probabilmente non sono la soluzione migliore al tuo problema. L'opzione "ALLOW-FROM" è stata totalmente disabilitata da tutti i principali browser.

La soluzione moderna consiste nell'implementare una politica di sicurezza dei contenuti e impostare una politica "frame_ancestors". La chiave "frame_ancestors" indica quali domini possono incorporare la tua app come iframe. È attualmente supportato dai principali browser e sovrascrive le opzioni X-Frame. Ciò ti consentirà di prevenire il clickjacking (che X-Frame-Options era originariamente previsto per aiutare prima che diventasse in gran parte deprecato) e di bloccare la tua app in un ambiente moderno.

Puoi impostare una Content-Security-Policy con Rails 5.2 in un inizializzatore (esempio sotto) e per Rails <5.2 puoi usare un gem come Secure Headers gem: https://github.com/github/secure_headers

Se lo desideri, puoi anche sovrascrivere le specifiche dei criteri in base al controller / azione.

I criteri di sicurezza dei contenuti sono ottimi per protezioni di sicurezza avanzate. Controlla tutte le cose che puoi configurare nella documentazione di Rails: https://edgeguides.rubyonrails.org/security.html

Un esempio di Rails 5.2 per una 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

Un esempio di una modifica specifica del controller a una politica:

# 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

Può anche utilizzare un lambda per i valori dinamici:p.frame_ancestors :self, -> { company&.allowed_domain || 'none' }
Sharagoz

0

Per Rails 5+, usa response.set_header('X-Frame-Options', 'ALLOW-FROM https://apps.facebook.com')invece. Oppure, se ALLOW-FROMnon funziona e hai bisogno di una soluzione rapida, puoi impostarla suALLOWALL

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.