VYPR
Medium severity4.8OSV Advisory· Published Sep 20, 2024· Updated Apr 15, 2026

CVE-2024-45793

CVE-2024-45793

Description

Confidant is a open source secret management service that provides user-friendly storage and access to secrets. The following endpoints are subject to a cross site scripting vulnerability: GET /v1/credentials, GET /v1/credentials/, GET /v1/archive/credentials/, GET /v1/archive/credentials, POST /v1/credentials, PUT /v1/credentials/, PUT /v1/credentials//<to_revision>, GET /v1/services, GET /v1/services/, GET /v1/archive/services/, GET /v1/archive/services, PUT /v1/services/, PUT /v1/services//<to_revision>. The attacker needs to be authenticated and have privileges to create new credentials, but could use this to show information and run scripts to other users into the same Confidant instance. This issue has been patched in version 6.6.2. All users are advised to upgrade. There are no known workarounds for this vulnerability.

AI Insight

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

Stored XSS in Confidant API endpoints could allow authenticated attackers to inject scripts affecting other users; patched in v6.6.2.

Vulnerability

CVE-2024-45793 is a stored cross-site scripting (XSS) vulnerability in Confidant, an open-source secret management service. The vulnerability affects multiple API endpoints handling credentials and services, including GET, POST, and PUT operations [1]. The root cause is insufficient sanitization of user-supplied input returned in API responses, allowing HTML/JavaScript injection.

Exploitation

An attacker must be authenticated and have privileges to create or modify credentials or services. By submitting crafted input, the attacker can store malicious scripts that are later served to other users accessing the same Confidant instance. The attacker does not need high privileges beyond the ability to create credentials [4].

Impact

Successful exploitation enables the attacker to execute arbitrary scripts in the context of other users' browsers, potentially leading to theft of session tokens, credential exposure, or other malicious actions within the Confidant UI [1][4]. This is a stored XSS with moderate severity (CVSS 4.8).

Mitigation

The issue has been patched in Confidant version 6.6.2, released on 2024-09-20. The fix adds a prevent_xss_decorator to affected endpoints [2]. All users should upgrade immediately; no workarounds are available [1][4]. Note that the Confidant repository has since been archived (February 2025) [3], meaning no further updates will be provided for older versions.

AI Insight generated on May 20, 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
confidantPyPI
< 6.6.26.6.2

Affected products

3
  • Lyft/ConfidantOSV2 versions
    1.1.19, 1.1.20, 1.1.21, …+ 1 more
    • (no CPE)range: 1.1.19, 1.1.20, 1.1.21, …
    • (no CPE)range: <6.6.2
  • ghsa-coords
    Range: < 6.6.2

Patches

1
8876b07abde0

Prevent XSS from API call (#436)

https://github.com/lyft/confidantWenchong HuSep 13, 2024via ghsa
6 files changed · +46 2
  • CHANGELOG.md+4 0 modified
    @@ -1,5 +1,9 @@
     # Changelog
     
    +## 6.6.2
    +
    +* XSS security fix / enhancement for Flask API response
    +
     ## 6.6.1
     
     * Upgrade confidant to python 3.10.14
    
  • confidant/routes/credentials.py+7 0 modified
    @@ -36,6 +36,7 @@
     
     
     @blueprint.route('/v1/credentials', methods=['GET'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     def get_credential_list():
         """
    @@ -132,6 +133,7 @@ def get_credential_list():
     
     
     @blueprint.route('/v1/credentials/<id>', methods=['GET'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     def get_credential(id):
         """
    @@ -369,6 +371,7 @@ def diff_credential(id, old_revision, new_revision):
     
     
     @blueprint.route('/v1/archive/credentials/<id>', methods=['GET'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     def get_archive_credential_revisions(id):
         """
    @@ -451,6 +454,7 @@ def get_archive_credential_revisions(id):
     
     
     @blueprint.route('/v1/archive/credentials', methods=['GET'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     def get_archive_credential_list():
         """
    @@ -534,6 +538,7 @@ def get_archive_credential_list():
     
     
     @blueprint.route('/v1/credentials', methods=['POST'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     @authnz.require_csrf_token
     @maintenance.check_maintenance_mode
    @@ -727,6 +732,7 @@ def get_credential_dependencies(id):
     
     
     @blueprint.route('/v1/credentials/<id>', methods=['PUT'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     @authnz.require_csrf_token
     @maintenance.check_maintenance_mode
    @@ -952,6 +958,7 @@ def update_credential(id):
     
     
     @blueprint.route('/v1/credentials/<id>/<to_revision>', methods=['PUT'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     @authnz.require_csrf_token
     @maintenance.check_maintenance_mode
    
  • confidant/routes/services.py+7 0 modified
    @@ -76,6 +76,7 @@ def get_iam_roles_list():
     
     
     @blueprint.route('/v1/services', methods=['GET'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     def get_service_list():
         """
    @@ -164,10 +165,12 @@ def get_service_list():
                 services_response = ServicesResponse.from_services(
                     Service.data_type_date_index.query('service'),
                 )
    +
             return services_response_schema.dumps(services_response)
     
     
     @blueprint.route('/v1/services/<id>', methods=['GET'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     def get_service(id):
         '''
    @@ -334,6 +337,7 @@ def get_service(id):
     
     
     @blueprint.route('/v1/archive/services/<id>', methods=['GET'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     def get_archive_service_revisions(id):
         """
    @@ -414,6 +418,7 @@ def get_archive_service_revisions(id):
     
     
     @blueprint.route('/v1/archive/services', methods=['GET'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     def get_archive_service_list():
         """
    @@ -492,6 +497,7 @@ def get_archive_service_list():
     
     
     @blueprint.route('/v1/services/<id>', methods=['PUT'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     @authnz.require_csrf_token
     @maintenance.check_maintenance_mode
    @@ -701,6 +707,7 @@ def map_service_credentials(id):
     
     
     @blueprint.route('/v1/services/<id>/<to_revision>', methods=['PUT'])
    +@misc.prevent_xss_decorator
     @authnz.require_auth
     @authnz.require_csrf_token
     @maintenance.check_maintenance_mode
    
  • confidant/utils/misc.py+27 0 modified
    @@ -1,6 +1,8 @@
    +from functools import wraps
     import importlib
     import pytz
     from datetime import datetime
    +from flask import make_response
     
     
     def dict_deep_update(a, b):
    @@ -54,3 +56,28 @@ def utcnow():
         """
         now = datetime.utcnow()
         return now.replace(tzinfo=pytz.utc)
    +
    +
    +def prevent_xss_decorator(func):
    +    """
    +    Prevents XSS attacks:
    +     1. Set content type to be application/json
    +     2. Set Content Security Policy (already specified at app level)
    +     3. Enable XSS Protection
    +     4. Prevent MIME Type Sniffing
    +     5. Limit Referrer Information
    +    """
    +    @wraps(func)
    +    def wrapper(*args, **kwargs):
    +        # Call the original function to get the response
    +        pre_xss_response = func(*args, **kwargs)
    +
    +        # Apply XSS prevention
    +        response = make_response(pre_xss_response)
    +        response.headers['Content-Type'] = 'application/json'
    +        response.headers['X-XSS-Protection'] = '1; mode=block'
    +        response.headers['X-Content-Type-Options'] = 'nosniff'
    +        response.headers['Referrer-Policy'] = 'no-referrer'
    +
    +        return response
    +    return wrapper
    
  • docker-compose.yml+0 1 modified
    @@ -1,4 +1,3 @@
    -version: "3.8"
     networks:
       confidant:
         name: confidant
    
  • VERSION+1 1 modified
    @@ -1 +1 @@
    -6.6.1
    +6.6.2
    

Vulnerability mechanics

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

References

7

News mentions

0

No linked articles in our index yet.