¿Qué hace force_ssl en Rails?

84

En una pregunta anterior , descubrí que debería configurar la terminación nginx ssl y no hacer que Rails procese datos cifrados.

Entonces, ¿por qué existe lo siguiente?

config.force_ssl = true

Veo esto comentado en el archivo de configuración de producción. Pero si la expectativa es que nginx manejará todas las cosas ssl para que mi aplicación rails no maneje datos encriptados, ¿qué hace config.force_ssl = true?

¿Debo dejarlo comentado en producción si sé que siempre usaré nginx?

user782220
fuente

Respuestas:

77

No solo obliga a su navegador a redirigir HTTP a HTTPS. También configura sus cookies para que se marquen como "seguras" y habilita HSTS , cada una de las cuales son muy buenas protecciones contra la eliminación de SSL.

Aunque HTTPS protege su aplicación en " https://example.com/yourapp " contra ataques MITM, si alguien se interpone entre su cliente y su servidor, puede hacer que visite fácilmente " http://example.com/yourapp " . Sin ninguna de las protecciones anteriores, su navegador enviará felizmente la cookie de sesión a la persona que realiza el MITM.

Dan Jameson
fuente
1
La fuente de force_ssl no contiene ninguna indicación de que HSTS esté habilitado por esta opción
agios
13
@agios Esta es una force_sslpropiedad separada por controlador . La force_sslvariable de configuración, que instala el Rack::SSLmiddleware, que habilita HSTS de forma predeterminada .
Brent Royal-Gordon
@agios, estás buscando en el lugar equivocado: github.com/rails/rails/blob/…
jmera
4
parece que config.force_ssl = truedebería ser el predeterminado, ¿por qué el equipo de Rails lo comentó como predeterminado?
Henry Yang
55

El entorno config.force_sslincluye ActionDispatch::SSL. Los ActionDispatch::SSLdocumentos describen la funcionalidad de la siguiente manera (énfasis agregado para mayor claridad):

Consulte las inclusiones aquí y los documentos de ActionDispatch :: SSL aquí .

DOCS

Este middleware se agrega a la pila cuando config.force_ssl = truese pasan las opciones establecidas en config.ssl_options. Realiza tres trabajos para hacer cumplir las solicitudes HTTP seguras:

  1. Redireccionamiento TLS: Redirige permanentemente las solicitudes http: // a https: // con el mismo host de URL, ruta, etc. Habilitado de forma predeterminada. Configure config.ssl_options para modificar la URL de destino (p redirect: { host: "secure.widgets.com", port: 8080 }. Ej. ), O configure redirect: falsepara deshabilitar esta función.

  2. Cookies seguras: establece la securemarca en las cookies para indicar a los navegadores que no deben enviarse junto con solicitudes http: //. Habilitado por defecto. Configure config.ssl_optionscon secure_cookies: falsepara deshabilitar esta función.

  3. Seguridad de transporte estricta HTTP (HSTS): le dice al navegador que recuerde este sitio como solo TLS y redirija automáticamente las solicitudes que no sean TLS . Habilitado por defecto. Configure config.ssl_optionscon hsts: falsepara deshabilitar. Establecer config.ssl_optionscon hsts: { … }para configurar HSTS:

    • expires: Cuánto tiempo, en segundos, se mantendrán estos ajustes. El valor predeterminado es 180.days(recomendado). El mínimo requerido para calificar para las listas de precarga del navegador es 18.weeks.
    • subdomains: Configúrelo para trueindicarle al navegador que aplique esta configuración a todos los subdominios. Esto protege sus cookies de la interceptación de un sitio vulnerable en un subdominio. Por defecto es true.
    • preload: Anuncie que este sitio puede estar incluido en las listas HSTS precargadas de los navegadores. HSTS protege su sitio en cada visita, excepto en la primera visita, ya que aún no ha visto su encabezado HSTS. Para cerrar esta brecha, los proveedores de navegadores incluyen una lista integrada de sitios habilitados para HSTS. Vaya a https://hstspreload.appspot.com para enviar su sitio para su inclusión. Para desactivar HSTS, omitir el encabezado no es suficiente. Los navegadores recordarán la directiva HSTS original hasta que expire. En su lugar, use el encabezado para indicar a los navegadores que expiren HSTS inmediatamente. La configuración hsts: falsees un atajo para hsts: { expires: 0 }.

Las solicitudes pueden excluirse de la redirección con exclude:

config.ssl_options = { redirect: { exclude: -> request { request.path =~ /healthcheck/ } } }
acero
fuente
3
"Las solicitudes pueden optar por dejar de redirección con exclude" - Advertencia: esta función sólo se ha añadido recientemente en los carriles 5, por lo que no funcionará para aquellos de nosotros en los carriles o por debajo de 4.2
jonleighton
1
Creo que las excludeopciones globales estaban disponibles mucho antes de Rails 5, por lo que su sintaxis es ligeramente diferente: config.ssl_options = { exclude: proc { |env| env['PATH_INFO'].start_with?('/healthcheck/') } }- serverfault.com/a/517401
jwadsack
12

Esta configuración fuerza HTTPS al redirigir las solicitudes HTTP a sus contrapartes HTTPS. Por tanto, una visita del navegador http://domain.com/pathserá redirigida a https://domain.com/path.

Dejar el entorno comentado permitiría ambos protocolos.

Aún tiene que configurar su servidor web para manejar solicitudes HTTPS.

Stefan
fuente
1
Pero si habilita HTTPS en el nivel de nginx (redirigiendo todo a HTTPS a través de redirect 301 https:...), ¿TODO no pasará por https, por lo config.force_ssl = trueque realmente no hace nada (ya que nada será http)? ¿O hay una razón de seguridad más profunda aquí?
Tristan Tao
2
@TristanTao sí, eso funcionaría igual de bien. Pero incluso entonces, lo dejaría config.force_sslhabilitado, en caso de que alguien esté eliminando la redirección de la configuración del servidor web.
Stefan
2
tenga cuidado, config.force_ssl es un poco diferente de force_ssl en el controlador en términos de proteger las cookies contra el secuestro de sesiones, más aquí: eq8.eu/blogs/…
equivalente 8
1
También tenga en cuenta que tener ambos config.force_ssly add_header Strict-Transport-Security max-age=...;resultará en 2 Strict-Transport-Securityencabezados
Victor Ivanov