Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/launcher.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
require 'openssl'
require 'proxy/log'

begin
require 'rackup/handler/webrick'
WEBRICK_HANDLER = Rackup::Handler::WEBrick
rescue LoadError
require 'rack'
WEBRICK_HANDLER = Rack::Handler::WEBrick
end
require 'proxy/settings'
require 'proxy/signal_handler'
require 'proxy/log_buffer/trace_decorator'
Expand Down Expand Up @@ -191,7 +199,7 @@ def webrick_server(app, addresses, port)
rescue ::OpenSSL::SSL::SSLError => e
raise "Invalid tls_ciphers value '#{app[:SSLCiphers]}': #{e.message}"
end
server.mount "/", Rack::Handler::WEBrick, app[:app]
server.mount "/", WEBRICK_HANDLER, app[:app]

# WEBrick 1.9.x does not support :SSLMinVersion in its config hash, so we
# apply min_version= directly on the SSL context after WEBrick creates it.
Expand Down
8 changes: 6 additions & 2 deletions lib/proxy/hsts_middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ module Proxy
# is needed.
# https://www.tenable.com/plugins/nessus/142960
class HstsMiddleware
# Lowercase is required by Rack 3 (https://github.com/rack/rack/issues/1592);
# Rack 2 doesn't care about header key case, so this works for both.
HEADER_KEY = 'strict-transport-security'.freeze

def initialize(app)
@app = app
end

def call(env)
status, headers, body = @app.call(env)
if env['HTTPS'] == 'on' && !headers.include?('Strict-Transport-Security')
headers['Strict-Transport-Security'] = 'max-age=31536000'
if env['HTTPS'] == 'on' && !headers.include?(HEADER_KEY)
headers[HEADER_KEY] = 'max-age=31536000'
end
[status, headers, body]
end
Expand Down
6 changes: 5 additions & 1 deletion lib/smart_proxy_main.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ module Proxy
::Sinatra::Base.use ::Proxy::RequestIdMiddleware
::Sinatra::Base.use ::Proxy::LoggerMiddleware
::Sinatra::Base.use ::Proxy::HstsMiddleware
::Sinatra::Base.set :env, :production
# Without this, Sinatra defaults to :development, which in Sinatra 4
# enables strict Rack::Protection::HostAuthorization that rejects
# requests whose Host header isn't localhost — breaking all real
# deployments where Foreman reaches smart-proxy by hostname.
::Sinatra::Base.set :environment, :production

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intended to be a fix for an issue that @ibuclaw raised.
The other option (using trusted_hosts in permitted_hosts context) wouldn't IMO make sense because one is about request origin, the other is about request target.

This line has been there for a long time and I think it was a bug - the correct symbol is :environment https://sinatrarb.com/configuration.html . It seems like it has been unnoticed for a long time. Note that changing environment can have consequences beyond just this fix - different security rules or logging content and others - I'm not certain what exactly. So this change needs to be weighed carefully.
In either case, the test suite is still green and the proxy still seems to work after this change.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, thanks.

That wrong name explains why I couldn't find environment anywhere.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for warning me about this, @ibuclaw !

::Sinatra::Base.register ::Sinatra::Authorization

require 'root/root'
Expand Down
5 changes: 5 additions & 0 deletions modules/registration/registration_api.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
require 'registration/proxy_request'

class Proxy::Registration::Api < ::Sinatra::Base
# Needed so `logger` resolves to Proxy::LogBuffer::Decorator (which implements
# #exception, used in the rescue blocks below) instead of Sinatra's own null
# logger, which is a plain ::Logger with no #exception method as of Sinatra 4.
helpers ::Proxy::Helpers
Comment on lines +4 to +7

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is a bug we've had that went unnoticed for a long time


# Cache for the global registration script (GET /register).
#
# The script is identical for all hosts sharing the same registration
Expand Down
5 changes: 3 additions & 2 deletions smart_proxy.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ Gem::Specification.new do |s|
s.add_dependency 'json'
s.add_dependency 'logging'
s.add_dependency 'ostruct'
s.add_dependency 'rack', '>= 1.3'
s.add_dependency 'rack', '>= 2.0', '< 4'
s.add_dependency 'rackup'
s.add_dependency 'rexml', '~> 3.2'
s.add_dependency 'sd_notify', '~> 0.1'
s.add_dependency 'sinatra', '~> 2.0'
s.add_dependency 'sinatra', '>= 2.0', '< 5'
s.add_dependency 'webrick', '~> 1.0'
s.description = <<~EOF
Foreman Proxy is used via The Foreman Project, it allows Foreman to manage
Expand Down
Loading