Cách ghi đè X-Frame-Options cho bộ điều khiển hoặc hành động trong Rails 4


88

Rails 4 dường như đặt giá trị mặc định SAMEORIGINcho X-Frame-Optionstiêu đề phản hồi HTTP. Điều này rất tốt cho bảo mật, nhưng nó không cho phép các phần của ứng dụng của bạn khả dụng iframetrên một miền khác.

Bạn có thể ghi đè giá trị của X-Frame-Optionstoàn cục bằng cách sử dụng config.action_dispatch.default_headerscài đặt:

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

Nhưng làm thế nào để bạn ghi đè nó chỉ cho một bộ điều khiển hoặc hành động duy nhất?

Câu trả lời:


136

Nếu bạn muốn xóa tiêu đề hoàn toàn, bạn có thể tạo một after_actionbộ lọc:

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

  def embed
  end

private

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

Hoặc, tất nhiên, bạn có thể viết mã after_actionđể đặt giá trị thành một giá trị khác:

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

Lưu ý rằng bạn cần xóa bộ nhớ cache của mình trong một số trình duyệt nhất định (đối với tôi là Chrome) trong khi gỡ lỗi này.


Làm thế nào bạn có thể làm cho điều này hoạt động trên redirect_to? (Am cố gắng ngay bây giờ với ứng dụng kiễu góc của tôi và nó không phải đang làm việc)
kittyminky

Tôi giả định rằng cả hành động có chứa redirect_tovà hành động mà nó chuyển hướng đến sẽ cần điều này được áp dụng. Bạn có đang gặp một lỗi cụ thể không? Có vẻ như một câu hỏi mới hay trên Stack Overflow!
Chris Peters

Tôi nhận ra rằng tôi đã có after_action trước khi nó được chuyển hướng đến hành động điều khiển cuối cùng chuyển hướng đến các Angulartuyến đường. Cảm ơn bạn!
kittyminky

Không bắt buộc phải làm điều này trong một after_action, mặc dù rất tiện lợi khi làm như vậy, ví dụ như ở Frontend::BaseControllernơi nó áp dụng cho toàn bộ giao diện người dùng. Bạn cũng có thể chạy response.headers.except! ...trong một hành động.
codener

2
Hiện tại, không hoạt động trong Chrome. Lỗi bảng điều khiển là "Gặp phải tiêu đề 'X-Frame-Options' không hợp lệ khi tải 'con': 'ALLOW-FROM cha' không phải là lệnh được công nhận. Tiêu đề này sẽ bị bỏ qua." Được đánh dấu là sẽ không khắc phục được trong Chromium, với một giải pháp thay thế: "'frame-parent' đang được cung cấp trong cả Chrome và Firefox và là cách phù hợp để hỗ trợ chức năng này." bug.chromium.org/p/chromium/issues/detail?id=129139
richardkmiller

4

Tôi chỉ muốn đưa câu trả lời cập nhật vào đây cho bất kỳ ai tìm thấy liên kết này khi cố gắng tìm ra cách cho phép ứng dụng Rails của bạn được nhúng vào I-Frame và gặp sự cố.

Khi viết bài này, ngày 28 tháng 5 năm 2020, các thay đổi X-Frame-Options có lẽ không phải là giải pháp tốt nhất cho vấn đề của bạn. Tùy chọn "CHO ​​PHÉP TỪ" hoàn toàn không được phép bởi tất cả các trình duyệt chính.

Giải pháp hiện đại là thực hiện Chính sách-Bảo mật-Nội dung và đặt chính sách 'Tổ tiên khung'. Khóa 'frame_ancestors' chỉ định miền nào có thể nhúng ứng dụng của bạn dưới dạng iframe. Nó hiện được hỗ trợ bởi các trình duyệt chính và ghi đè X-Frame-Options của bạn. Điều này sẽ cho phép bạn ngăn chặn Clickjacking (mà X-Frame-Options ban đầu được dự định để trợ giúp trước khi nó phần lớn không được dùng nữa) và khóa ứng dụng của bạn trong một môi trường hiện đại.

Bạn có thể thiết lập Nội dung-Bảo mật-Chính sách với Rails 5.2 trong trình khởi tạo (ví dụ bên dưới) và đối với Rails <5.2, bạn có thể sử dụng một viên đá quý như đá quý Secure Headers: https://github.com/github/secure_headers

Bạn cũng có thể ghi đè các thông số kỹ thuật chính sách trên cơ sở bộ điều khiển / hành động nếu bạn muốn.

Nội dung-Bảo mật-Chính sách là rất tốt cho các biện pháp bảo mật nâng cao. Kiểm tra tất cả những thứ bạn có thể định cấu hình trong tài liệu Rails: https://edgeguides.rubyonrails.org/security.html

Ví dụ về Rails 5.2 cho Nội dung-Bảo mật-Chính sách:

# 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

Ví dụ về thay đổi cụ thể của bộ điều khiển đối với chính sách:

# 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

Cũng có thể sử dụng lambda cho các giá trị động:p.frame_ancestors :self, -> { company&.allowed_domain || 'none' }
Sharagoz

0

Đối với Rails 5+, hãy sử dụng response.set_header('X-Frame-Options', 'ALLOW-FROM https://apps.facebook.com')thay thế. Hoặc nếu ALLOW-FROMkhông hoạt động và bạn cần sửa chữa nhanh, bạn có thể đặt nó thànhALLOWALL

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.