VYPR
Low severityNVD Advisory· Published Nov 25, 2019· Updated Aug 5, 2024

CVE-2019-14825

CVE-2019-14825

Description

A cleartext password storage issue was discovered in Katello, versions 3.x.x.x before katello 3.12.0.9. Registry credentials used during container image discovery were inadvertently logged without being masked. This flaw could expose the registry credentials to other privileged users.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Katello 3.x versions prior to 3.12.0.9 logged container registry credentials in plaintext, allowing other privileged users to capture them.

### root cause CVE-2019-14825 is a cleartext password storage vulnerability in Katello (content management plugin for Red Hat Satellite). The bug resides in the container image discovery feature. When Katello discovers container images from external registries, the authentication credentials (username and password) used for registry access were written to log files without any masking or redaction. [1][4]

### exploitation The vulnerability requires the attacker to already have privileged access to the Katello server, such that they can read log files produced by the application. No special authentication to the registry is needed beyond the credentials already stored by Katello. The attack vector is local to the system logs. [1][2]

### impact A privileged adversary who can access the application logs obtains the cleartext registry credentials. These credentials can then be reused to authenticate to the container registry directly, potentially allowing the attacker to pull or push container images, or access other resources protected by the same credentials. [1][4]

### mitigation Red Hat released an advisory RHSA-2019:3172 for Satellite 6.6, and the fix was included in Katello version 3.12.0.9. Users should update to this version or later. The GitHub pull request [3] references the fix that clears or masks the credentials from proxy settings in logs. No workarounds are documented; updating is the recommended action. [1][3]

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
katelloRubyGems
>= 3.0.0.0, < 3.12.23.12.2

Affected products

2
  • ghsa-coords
    Range: >= 3.0.0.0, < 3.12.2
  • Red Hat/katellov5
    Range: katello versions 3.x.x.x before katello 3.12.0.9

Patches

2
332484232b66

Refs #27485 - Clear proxy settings for tests

https://github.com/Katello/katelloChris RobertsAug 5, 2019via ghsa
1 file changed · +1 0
  • test/actions/katello/repository/discover_test.rb+1 0 modified
    @@ -13,6 +13,7 @@ module Actions
         let(:action_class) { ::Actions::Katello::Repository::Discover }
     
         def setup
    +      SETTINGS[:katello][:cdn_proxy] = {}
           get_organization #ensure we have an org label
         end
     
    
4eefa678a905

Fixes #27485 - encrypt discovery password within task

https://github.com/Katello/katelloJustin SherrillJul 31, 2019via ghsa
2 files changed · +57 12
  • app/lib/actions/katello/repository/discover.rb+10 12 modified
    @@ -1,8 +1,9 @@
     module Actions
       module Katello
         module Repository
    -      class Discover < Actions::Base
    +      class Discover < Actions::EntryAction
             include Dynflow::Action::Cancellable
    +        include EncryptValue
     
             input_format do
               param :url, String
    @@ -17,22 +18,24 @@ class Discover < Actions::Base
             end
     
             def plan(url, content_type, upstream_username, upstream_password, search)
    -          plan_self(url: url, content_type: content_type, upstream_username: upstream_username, upstream_password: upstream_password, search: search)
    +          password = encrypt_field(upstream_password)
    +          plan_self(url: url, content_type: content_type, upstream_username: upstream_username, upstream_password: password, search: search)
             end
     
             def run(event = nil)
               output[:repo_urls] = output[:repo_urls] || []
               output[:crawled] = output[:crawled] || []
               output[:to_follow] = output[:to_follow] || [input[:url]]
     
    -          repo_discovery = ::Katello::RepoDiscovery.new(input[:url], input[:content_type],
    -                                                        input[:upstream_username], input[:upstream_password],
    -                                                        input[:search], proxy,
    -                                                        output[:crawled], output[:repo_urls], output[:to_follow])
    -
               match(event,
                 (on nil do
                   unless output[:to_follow].empty?
    +                password = decrypt_field(input[:upstream_password])
    +                repo_discovery = ::Katello::RepoDiscovery.new(input[:url], input[:content_type],
    +                                                              input[:upstream_username], password,
    +                                                              input[:search], proxy,
    +                                                              output[:crawled], output[:repo_urls], output[:to_follow])
    +
                     repo_discovery.run(output[:to_follow].shift)
                     suspend { |suspended_action| world.clock.ping suspended_action, 0.001 }
                   end
    @@ -42,11 +45,6 @@ def run(event = nil)
                 end))
             end
     
    -        # @return <String> urls found by the action
    -        def task_input
    -          input[:url]
    -        end
    -
             # @return [Array<String>] urls found by the action
             def task_output
               output[:repo_urls] || []
    
  • test/actions/katello/repository/discover_test.rb+47 0 added
    @@ -0,0 +1,47 @@
    +require 'katello_test_helper'
    +
    +module EncryptionKey
    +  ENCRYPTION_KEY = nil
    +end
    +
    +module Actions
    +  describe Katello::Repository::CloneToVersion do
    +    include Dynflow::Testing
    +    include Support::Actions::Fixtures
    +    include FactoryBot::Syntax::Methods
    +
    +    let(:action_class) { ::Actions::Katello::Repository::Discover }
    +
    +    def setup
    +      get_organization #ensure we have an org label
    +    end
    +
    +    def test_discovers_without_encryption
    +      EncryptionKey.const_set(:ENCRYPTION_KEY, nil)
    +
    +      mock_discovery = mock
    +      url = 'http://foo.com'
    +      ::Katello::RepoDiscovery.expects(:new).with(url, 'yum', 'admin', 'secret', nil, {}, [], [], [url]).returns(mock_discovery)
    +      mock_discovery.expects(:run).with("http://foo.com").once
    +
    +      task = ForemanTasks.sync_task(action_class, url, 'yum', 'admin', 'secret', nil)
    +
    +      refute_empty task.input[:upstream_password]
    +      assert_equal task.input[:upstream_password], 'secret'
    +    end
    +
    +    def test_discovers_with_hidden_password
    +      EncryptionKey.const_set(:ENCRYPTION_KEY, 'ebf26a286b3edec3d31ac10e8e97bd60')
    +
    +      mock_discovery = mock
    +      url = 'http://foo.com'
    +      ::Katello::RepoDiscovery.expects(:new).with(url, 'yum', 'admin', 'secret', nil, {}, [], [], [url]).returns(mock_discovery)
    +      mock_discovery.expects(:run).with("http://foo.com").once
    +
    +      task = ForemanTasks.sync_task(action_class, url, 'yum', 'admin', 'secret', nil)
    +
    +      refute_empty task.input[:upstream_password]
    +      refute_equal task.input[:upstream_password], 'secret'
    +    end
    +  end
    +end
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

14

News mentions

0

No linked articles in our index yet.