Deprecate controller level force_ssl#32277
Deprecate controller level force_ssl#32277guilleiguaran merged 1 commit intorails:masterfrom derekprior:dp-deprecate-force-ssl
Conversation
|
r? @sgrif (@rails-bot has picked a reviewer for you, use r? to override) |
There was a problem hiding this comment.
capital 'Y' in 'You'
Unrelated: I enjoy your show 🚲 🔔 and I am looking forward to your talk at RailsConf.
There was a problem hiding this comment.
Another place here re: 6.0 -> 6.1.
There was a problem hiding this comment.
One more thing — Look like "You" in "you are encouraged ..." has to be capitalized.
sikachu
left a comment
There was a problem hiding this comment.
I have a few comments. Would love to @fxn's or @pixeltrix thought about the documentation aspect of this though. 🙇
There was a problem hiding this comment.
Another place here re: 6.0 -> 6.1.
|
@derekprior not 100% convinced of the misconfiguration argument - it's not something I've personally seen in the past few years on a variety of Rails apps and there's been one occurrence on a high-profile website I support where adding However it's not a hill I willing to die on if other Rails maintainers feel differently. |
|
@pixeltrix I should have been more specific when I said "many apps". I've seen it 4 times that I remember in the last few years of projects (3~6/year). Most recently, I submitted a PR to a project to switch to That said, I certainly expected some debate of this PR. I can see your points as well. I just think the expectation is that applications work entirely over HTTPS these days and that Rails should optimize for that. I feel like I'd be less likely to object to the controller-level construct if it wasn't identically named to the middleware level configuration. |
The problem is that not everything is possible through Maybe this is fine given the timeframe - it's not going to be removed until 6.1 which will likely be at least 18-24 months away. |
|
I'm 100% in favor of this change (other than the version changes), but I will defer to @pixeltrix on this. r? @pixeltrix |
|
Giving the timing I'm fine with deprecating this feature in Rails 6.0 too. @jeremy care to review this too given you did the last improvement on the SSL middleware? |
|
@derekprior would you mind fixing the documentation issue? We should be able to merge it in afterward. |
|
@sikachu Docs updated. I added |
sikachu
left a comment
There was a problem hiding this comment.
Yep, that's fine! I want to leave the comment there for original code spelunker as well, just want it to disappear from the doc.
It looks like you need to do :nodoc: at the end of the class instead. Do you mind checking my diff?
There was a problem hiding this comment.
I tried this, and it actually didn't remove this from the documentation. Looks like you need to do explicit :nodoc: next to each class:
diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb
index 4b54b4a19e..b73d54edb3 100644
--- a/actionpack/lib/action_controller/metal/force_ssl.rb
+++ b/actionpack/lib/action_controller/metal/force_ssl.rb
@@ -4,12 +4,11 @@
require "active_support/core_ext/hash/slice"
module ActionController
- # :nodoc:
# This module is deprecated in favor of +config.force_ssl+ in your environment
# config file. This will ensure all communication to non-whitelisted endpoints
# served by your application occurs over HTTPS.
#
- module ForceSSL
+ module ForceSSL # :nodoc:
extend ActiveSupport::Concern
include AbstractController::Callbacks
@@ -17,7 +16,7 @@ module ForceSSL
URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path]
REDIRECT_OPTIONS = [:status, :flash, :alert, :notice]
- module ClassMethods
+ module ClassMethods # :nodoc:
def force_ssl(options = {})
ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
Controller-level `force_ssl` is deprecated and will be removed fromThere was a problem hiding this comment.
Thanks, updated.
Today there are two common ways for Rails developers to force their applications to communicate over HTTPS: * `config.force_ssl` is a setting in environment configurations that enables the `ActionDispatch::SSL` middleware. With this middleware enabled, all HTTP communication to your application will be redirected to HTTPS. The middleware also takes care of other best practices by setting HSTS headers, upgrading all cookies to secure only, etc. * The `force_ssl` controller method redirects HTTP requests to certain controllers to HTTPS. As a consultant, I've seen many applications with misconfigured HTTPS setups due to developers adding `force_ssl` to `ApplicationController` and not enabling `config.force_ssl`. With this configuration, many application requests can be served over HTTP such as assets, requests that hit mounted engines, etc. In addition, because cookies are not upgraded to secure only in this configuration and HSTS headers are not set, it's possible for cookies that are meant to be secure to be sent over HTTP. The confusion between these two methods of forcing HTTPS is compounded by the fact that they share an identical name. This makes finding documentation on the "right" method confusing. HTTPS throughout is quickly becomming table stakes for all web sites. Sites are expected to operate over HTTPS for all communication, sensitive or otherwise. Let's encourage use of the broader-reaching `ActionDispatch::SSL` middleware and elminate this source of user confusion. If, for some reason, applications need to expose certain endpoints over HTTP they can do so by properly configuring `config.ssl_options`.
|
Anybody have an idea how to allow Google Load Balancer health check with config.force_ssl? They always connect over HTTP and will thus get a redirect. Currently we can work around this by using force_ssl in the ApplicationController. |
|
I use this for AWS's ALB config.force_ssl = true
config.ssl_options = {
redirect: {
exclude: ->(request) { request.env["HTTP_X_FORWARDED_FOR"].blank? }
}
} |
|
Great, thank you very much! |
|
This change will make it harder to use HTTPS on Rails apps that offer custom domains to certain customers, when certificate generation is not automatic for everyone. Obviously it's possible to generate certs for every custom domain automatically, but it's not necessarily trivial. In other words, controller-level decision to use HTTPS (based on a database lookup for the hostname specified) seems like a reasonable thing to want to do in some circumstances. Is there any workaround to this? |
|
You can use So you could exclude based on host, path, headers, whatever... |
|
I saw that... but all the examples were extremely trivial like excluding one path. But I guess you're saying there's nothing stopping me from doing a Model/database lookup based on the host via |
Today there are two common ways for Rails developers to force their
applications to communicate over HTTPS:
config.force_sslis a setting in environment configurations thatenables the
ActionDispatch::SSLmiddleware. With this middlewareenabled, all HTTP communication to your application will be redirected
to HTTPS. The middleware also takes care of other best practices by
setting HSTS headers, upgrading all cookies to secure only, etc.
force_sslcontroller method redirects HTTP requests to certaincontrollers to HTTPS.
As a consultant, I've seen many applications with misconfigured HTTPS
setups due to developers adding
force_ssltoApplicationControllerand not enabling
config.force_ssl. With this configuration, manyapplication requests can be served over HTTP such as assets, requests
that hit mounted engines, etc. In addition, because cookies are not
upgraded to secure only in this configuration and HSTS headers are not
set, it's possible for cookies that are meant to be secure to be sent
over HTTP.
The confusion between these two methods of forcing HTTPS is compounded
by the fact that they share an identical name. This makes finding
documentation on the "right" method confusing.
HTTPS throughout is quickly becomming table stakes for all web sites.
Sites are expected to operate over HTTPS for all communication,
sensitive or otherwise. Let's encourage use of the broader-reaching
ActionDispatch::SSLmiddleware and elminate this source of userconfusion. If, for some reason, applications need to expose certain
endpoints over HTTP they can do so by properly configuring
config.ssl_options.