From 6fc402e40ba998b2b5d94e09df7c693407d54a3e Mon Sep 17 00:00:00 2001 From: Ahmad Farhat Date: Fri, 8 May 2020 13:33:02 -0400 Subject: [PATCH] GRN2-xx: Added SAFE_HOSTS env variable to block unknown hosts (#1543) * Added SAFE_HOSTS env variable to block unknown hosts * Update sample.env --- app/controllers/application_controller.rb | 24 +++++++++++++++++++++-- app/controllers/concerns/errors.rb | 5 +++++ app/controllers/themes_controller.rb | 2 +- sample.env | 7 +++++++ 4 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 app/controllers/concerns/errors.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1e101f29..f7ec7b81 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -18,9 +18,10 @@ class ApplicationController < ActionController::Base include BbbServer + include Errors - before_action :redirect_to_https, :set_user_domain, :set_user_settings, :maintenance_mode?, :migration_error?, - :user_locale, :check_admin_password, :check_user_role + before_action :block_unknown_hosts, :redirect_to_https, :set_user_domain, :set_user_settings, :maintenance_mode?, + :migration_error?, :user_locale, :check_admin_password, :check_user_role protect_from_forgery with: :exceptions @@ -44,6 +45,14 @@ class ApplicationController < ActionController::Base @bbb_server ||= Rails.configuration.loadbalanced_configuration ? bbb(@user_domain) : bbb("greenlight") end + # Block unknown hosts to mitigate host header injection attacks + def block_unknown_hosts + return unless Rails.env.production? + valid_hosts = ENV["SAFE_HOSTS"] + return raise UnsafeHostError, "SAFE_HOSTS not set in .env" if valid_hosts.blank? + raise UnsafeHostError, "#{request.host} is not a safe host" unless host_is_valid(valid_hosts) + end + # Force SSL def redirect_to_https if Rails.configuration.loadbalanced_configuration && request.headers["X-Forwarded-Proto"] == "http" @@ -252,4 +261,15 @@ class ApplicationController < ActionController::Base end end end + + def host_is_valid(hosts) + hosts.split(",").each do |url| + # convert to regex + reg_url = url.gsub(".", "\\.") + sub_url = reg_url.gsub("*", ".{1,}") + + return true if request.host.match(sub_url) + end + false + end end diff --git a/app/controllers/concerns/errors.rb b/app/controllers/concerns/errors.rb new file mode 100644 index 00000000..9bb9f0c6 --- /dev/null +++ b/app/controllers/concerns/errors.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module Errors + class UnsafeHostError < StandardError; end +end diff --git a/app/controllers/themes_controller.rb b/app/controllers/themes_controller.rb index 79132b78..de38a8bc 100644 --- a/app/controllers/themes_controller.rb +++ b/app/controllers/themes_controller.rb @@ -17,7 +17,7 @@ # with BigBlueButton; if not, see . class ThemesController < ApplicationController - skip_before_action :redirect_to_https, :maintenance_mode?, :migration_error?, :user_locale, + skip_before_action :block_unknown_hosts, :redirect_to_https, :maintenance_mode?, :migration_error?, :user_locale, :check_admin_password, :check_user_role # GET /primary diff --git a/sample.env b/sample.env index 15dd119f..057263f9 100644 --- a/sample.env +++ b/sample.env @@ -16,6 +16,13 @@ SECRET_KEY_BASE= BIGBLUEBUTTON_ENDPOINT= BIGBLUEBUTTON_SECRET= +# The hostname that the application is accessible from. +# +# Used to protect against various HTTP header attacks +# Should be in the form of "domain.com" +# +SAFE_HOSTS= + # Google Login Provider (optional) # # For in-depth steps on setting up a Google Login Provider, see: