วิธีการแทนที่ X-Frame-Options สำหรับคอนโทรลเลอร์หรือการดำเนินการใน Rails 4


89

ดูเหมือนว่า 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!
Chris Peters

ฉันรู้ว่าฉันมีafter_action ก่อนที่จะเปลี่ยนเส้นทางไปยังการดำเนินการสุดท้ายของคอนโทรลเลอร์ที่เปลี่ยนเส้นทางไปยังAngularเส้นทาง ขอขอบคุณ!
kittyminky

ไม่จำเป็นต้องทำในส่วนafter_actionนี้แม้ว่าจะสะดวกเช่นในFrontend::BaseControllerกรณีที่ใช้กับส่วนหน้าทั้งหมด คุณสามารถresponse.headers.except! ...ดำเนินการได้เช่นกัน
codener

2
ณ ตอนนี้ไม่สามารถใช้งานได้ใน Chrome ข้อผิดพลาดของคอนโซลคือ "ส่วนหัว" X-Frame-Options "ไม่ถูกต้องพบเมื่อโหลด" ลูก ":" ALLOW-FROM parent "ไม่ใช่คำสั่งที่รู้จักส่วนหัวจะถูกละเว้น" ทำเครื่องหมายว่าจะไม่แก้ไขใน Chromium โดยมีอีกทางเลือกหนึ่งคือ "" frame-บรรพบุรุษ "กำลังจัดส่งทั้งใน Chrome และ Firefox และเป็นวิธีที่เหมาะสมในการสนับสนุนฟังก์ชันนี้" bugs.chromium.org/p/chromium/issues/detail?id=129139
richardkmiller

8

ฉันแค่อยากจะรวมคำตอบที่อัปเดตไว้ที่นี่สำหรับทุกคนที่พบลิงก์นี้เมื่อพยายามหาวิธีอนุญาตให้แอป Rails ของคุณฝังอยู่ใน I-Frame และพบปัญหา

เมื่อเขียนสิ่งนี้ 28 พฤษภาคม 2020 การเปลี่ยนแปลง X-Frame-Options อาจไม่ใช่วิธีแก้ปัญหาที่ดีที่สุดของคุณ ตัวเลือก "ALLOW-FROM" ไม่ได้รับอนุญาตจากเบราว์เซอร์หลัก ๆ ทั้งหมด

วิธีแก้ปัญหาที่ทันสมัยคือการใช้นโยบายเนื้อหา - ความปลอดภัยและกำหนดนโยบาย 'frame_ancestors' คีย์ "frame_ancestors" จะกำหนดโดเมนที่สามารถฝังแอปของคุณเป็น iframe ได้ ปัจจุบันรองรับโดยเบราว์เซอร์หลักและแทนที่ X-Frame-Options ของคุณ วิธีนี้จะช่วยให้คุณสามารถป้องกัน Clickjacking (ซึ่งเดิมที X-Frame-Options มีจุดมุ่งหมายเพื่อช่วยก่อนที่จะเลิกใช้งานส่วนใหญ่) และล็อกแอปของคุณในสภาพแวดล้อมที่ทันสมัย

คุณสามารถตั้งค่า Content-Security-Policy ด้วย Rails 5.2 ในตัวเริ่มต้น (ตัวอย่างด้านล่าง) และสำหรับ Rails <5.2 คุณสามารถใช้อัญมณีเช่น Secure Headers gem: https://github.com/github/secure_headers

นอกจากนี้คุณยังสามารถแทนที่ข้อกำหนดนโยบายบนพื้นฐานของตัวควบคุม / การดำเนินการได้หากต้องการ

Content-Security-Policies เหมาะสำหรับการป้องกันความปลอดภัยขั้นสูง ตรวจสอบทุกสิ่งที่คุณสามารถกำหนดค่าได้ในเอกสาร Rails: https://edgeguides.rubyonrails.org/security.html

ตัวอย่าง Rails 5.2 สำหรับ 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

ตัวอย่างการเปลี่ยนแปลงนโยบายเฉพาะของผู้ควบคุม:

# 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' }
ด้า

ฉันใช้งานframe_ancestorsและใช้ได้กับทุกเบราว์เซอร์ แต่ Safari ความเข้าใจใด ๆ ?
แมตต์

@Matt - ฉันเชื่อว่า Safari ในปัจจุบันป้องกัน iframe ของบุคคลที่สามจากการจัดเก็บคุกกี้ซึ่งเป็นข้อ จำกัด ที่สำคัญในการใช้ iframe ใน Safari และอาจเป็นสาเหตุของปัญหาของคุณ เท่าที่ฉันรู้ไม่มีวิธีการทำงานที่ดี ตรวจสอบสแตกล้นนี้สำหรับข้อมูลเพิ่มเติม: stackoverflow.com/questions/59723056/…
armont_development

0

สำหรับ Rails 5+ ให้ใช้response.set_header('X-Frame-Options', 'ALLOW-FROM https://apps.facebook.com')แทน หรือหากALLOW-FROMไม่ได้ผลและคุณต้องการการแก้ไขอย่างรวดเร็วคุณสามารถตั้งค่าเป็นALLOWALL

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.