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.