From c6fd18b25d1cbb293dfb50fa758f3a8d2b174dc1 Mon Sep 17 00:00:00 2001 From: Ben Ford Date: Mon, 8 Sep 2025 19:29:15 -0700 Subject: [PATCH 1/2] More secure default server setting Under some fairly obscure conditions, defaulting the server setting to 'puppet' can be a security concern. Because the worst case scenario involves a user accidentally running `puppet agent -t` on an untrusted network, this PR removes the default completely when non-root. Otherwise, it just prints a deprecation warning. The check and warnings are generated at the http service so that it only screams if you actually attempt to use it. This avoids, for example, the spurious deprecation message when running `puppet config set` to set this in the first place. Fixes https://github.com/voxpupuli/security-tracking/issues/22 --- lib/puppet/defaults.rb | 4 ++-- lib/puppet/http/service.rb | 18 ++++++++++++++++++ spec/unit/defaults_spec.rb | 25 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index f2f20282f7..0b47a3d783 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -863,7 +863,7 @@ def self.initialize_default_settings!(settings) **Note:** The list of alternate names is locked in when the server's certificate is signed. If you need to change the list later, you can't just change this setting; you also need to regenerate the certificate. For more -information on that process, see the +information on that process, see the [cert regen docs](https://puppet.com/docs/puppet/latest/ssl_regenerate_certificates.html). To see all the alternate names your servers are using, log into your CA server @@ -1650,7 +1650,7 @@ def self.initialize_default_settings!(settings) :desc => "The root directory of devices' $confdir.", }, :server => { - :default => "puppet", + :default => Puppet.features.root? ? 'puppet' : '', # use an empty string so dependent settings can resolve without crashing :desc => "The primary Puppet server to which the Puppet agent should connect. This setting is ignored when `server_list` is specified.", }, :server_list => { diff --git a/lib/puppet/http/service.rb b/lib/puppet/http/service.rb index e031450506..2efc1acf3f 100644 --- a/lib/puppet/http/service.rb +++ b/lib/puppet/http/service.rb @@ -32,6 +32,24 @@ class Puppet::HTTP::Service # # @api private def self.create_service(client, session, name, server = nil, port = nil) + # this is the entry point for creating all services, check and issue warning here. + unless Puppet.settings.set_by_config? :server + if Puppet.features.root? + Puppet.deprecation_warning('OpenVox will not default to `server=puppet` as of version 9.0. Please update your configuration appropriately.') + else + Puppet.deprecation_warning('OpenVox no longer defaults to `server=puppet` when running as a non-privileged user. (Did you mean to run as root?)') + + case name + when :ca + raise ArgumentError, 'Neither `server` nor `ca_server` is specified.' unless Puppet.settings.set_by_config? :ca_server + when :report + raise ArgumentError, 'Neither `server` nor `report_server` is specified.' unless Puppet.settings.set_by_config? :report_server + when :fileserver, :puppet, :puppetserver + raise ArgumentError, 'Required setting `server` is not specified.' + end + end + end + case name when :ca Puppet::HTTP::Service::Ca.new(client, session, server, port) diff --git a/spec/unit/defaults_spec.rb b/spec/unit/defaults_spec.rb index 9f322b38ec..5a1fd6a644 100644 --- a/spec/unit/defaults_spec.rb +++ b/spec/unit/defaults_spec.rb @@ -8,6 +8,31 @@ end end + describe 'server' do + it 'should default to `puppet` when root' do + allow(Puppet.features).to receive(:root?).and_return(true) + foo = Puppet::Settings.new + Puppet.initialize_default_settings!(foo) + expect(foo[:server]).to eq('puppet') + end + + it 'should default to empty value when non-root' do + allow(Puppet.features).to receive(:root?).and_return(false) + foo = Puppet::Settings.new + Puppet.initialize_default_settings!(foo) + expect(foo[:server]).to eq('') + end + + it 'should fail when trying to establish a compiler connection without setting `server`' do + allow(Puppet.features).to receive(:root?).and_return(false) + expect { + client = Puppet.runtime[:http] + session = client.create_session + service = session.route_to(:puppet) + }.to raise_exception ArgumentError, /Required setting/ + end + end + describe 'strict' do it 'should accept the valid value :off' do expect {Puppet.settings[:strict] = 'off'}.to_not raise_exception From 8a79383f6989c59a7a5f2591054bb847b10747d2 Mon Sep 17 00:00:00 2001 From: Ben Ford Date: Tue, 6 Jan 2026 17:16:45 -0800 Subject: [PATCH 2/2] fix spec tests Co-authored-by: Haroon Rafique --- spec/integration/application/lookup_spec.rb | 1 + spec/integration/configurer_spec.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/spec/integration/application/lookup_spec.rb b/spec/integration/application/lookup_spec.rb index 998b2617bd..db0a69db17 100644 --- a/spec/integration/application/lookup_spec.rb +++ b/spec/integration/application/lookup_spec.rb @@ -147,6 +147,7 @@ def expect_lookup_with_output(exitcode, out) end it 'loads trusted information from the node certificate' do + Puppet.settings[:server] = 'puppet' Puppet.settings[:node_terminus] = 'exec' expect_any_instance_of(Puppet::Node::Exec).to receive(:find) do |args| info = Puppet.lookup(:trusted_information) diff --git a/spec/integration/configurer_spec.rb b/spec/integration/configurer_spec.rb index 6e1823af94..b7bd852dc7 100644 --- a/spec/integration/configurer_spec.rb +++ b/spec/integration/configurer_spec.rb @@ -135,6 +135,7 @@ end it 'logs errors that occur during fact submission' do + Puppet[:server] = 'puppet' stub_request(:put, "https://puppet:8140/puppet/v3/facts/configurer.test?environment=production").to_return(status: 502) expect(Puppet).to receive(:log_exception).with(Puppet::HTTP::ResponseError, /^Failed to submit facts/)