¿Cómo se puede utilizar la infraestructura de rieles AuthenticityToken para proteger explícitamente una acción GET
-
13-09-2019 - |
Pregunta
Rieles AuthenticityToken protege automáticamente de POST / PUT / Eliminar solicitudes de ataques CSRF. Pero tengo otro caso de uso en mente.
Estoy mostrando un video en mi sitio que yo no quiero ser integrable en otros sitios. ¿Cómo funciona esto es que mi reproductor flash envía una solicitud para una dirección URL firmado de mi CDN, que expira en unos pocos segundos. Hasta ahora, un usuario tenía que estar conectado para ver vídeos, por lo que fue la autenticación. Sin embargo ahora quiero cualquier visitante de la página para poder ver el vídeo sin permitir la URL firmado para ser solicitada desde otro sitio (por ejemplo, si se incrustan nuestro jugador en su sitio).
Lo primero que pensé fue a AuthenticityToken ya que parece tener estos semántica exacta ... todo lo que necesita hacer es conectarlo a una petición GET. ¿Alguna idea?
Solución
Rieles, obstinado, ya que es cree que todas las peticiones GET deben idempotent. Esto significa, por supuesto, los carriles no comprueba la autenticidad fichas para peticiones GET, incluso verified_request? da a cada conseguir un pase.
def verified_request?
!protect_against_forgery? ||
request.method == :get ||
!verifiable_request_format? ||
form_authenticity_token == params[request_forgery_protection_token]
end
Así que tenemos que escribir nuestra propia lógica. Podemos utilizar símbolo form_authenticity. Todo esto hace es crear una cadena aleatoria y la memoria caché en la sesión:
def form_authenticity_token
session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32)
end
Por lo tanto, podemos hacer una antes de filtro que prueba la igualdad de un parámetro url para el token de sesión. asegurando así que sólo los visitantes pueden ver vídeos de buena fe.
controlador:
class CDNController < ActionController::Base
# You probably only want to verify the show action
before_filter :verify_request, :only => 'show'
# Regular controller actions…
protected
def verify_request
# Correct HTTP response code is 403 forbidden, not 404 not found.
render(:status => 403) unless form_authenticity_token == params[:token]
end
end
La vista:
<%= video_path(:token => form_authenticity_token) %>
Otros consejos
Para conectar el testigo de la autenticidad en su URL:
<%= video_path(:token => form_authenticity_token) %>
En el controlador de CDN, podrías comprobar si el testigo de la autenticidad es correcta con una before_filter:
def verify_token
render_404 unless form_authenticity_token == params[:token]
end
def render_404
render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
end