CVE-2025-1979
Ray <= 2.43.0 logs Redis password, potentially leaking sensitive information.
- CVSS 5.7
- CWE-532
- Information Leakage
- Remote
Versions of the package ray before 2.43.0 are vulnerable to Insertion of Sensitive Information into Log File where the redis password is being logged in the standard logging. If the redis password is passed as an argument, it will be logged and could potentially leak the password. This is only exploitable if: 1) Logging is enabled; 2) Redis is using password authentication; 3) Those logs are accessible to an attacker, who can reach that redis instance. **Note:** It is recommended that anyone who is running in this configuration should update to the latest version of Ray, then rotate their redis password.
- CWE
- CWE-532
- CVSS base score
- 5.7
- Published
- 2025-03-06
- OWASP
- A03:2021-Injection
- Orthogonal defect classification
- Interface
- Code defect classification
- Incorrect Functionality
- Category
- Information Leakage
- Subcategory
- Information Leakage
- Accessibility scope
- Remote
- Impact
- Information Disclosure
- Affected component
- Ray
- Fixed by upgrading
- Yes
Solution
Upgrade to ray >= 2.43.0 and rotate your Redis password.
Vulnerable code sample
import logging
logging.basicConfig(level=logging.INFO)
def start_redis_with_password(redis_password):
"""
Simulates starting Redis with a password, logging the password.
This function mimics the vulnerable behavior in ray versions before 2.43.0
where the Redis password could be inadvertently logged.
"""
logging.info(f"Starting Redis with password: {redis_password}")
# Example usage (mimicking the vulnerability)
redis_password = "my_secret_redis_password"
start_redis_with_password(redis_password)Patched code sample
import logging
import re
class SensitiveDataFilter(logging.Filter):
"""
A logging filter that redacts sensitive information like Redis passwords.
"""
def __init__(self, sensitive_patterns):
"""
Initializes the filter with a list of regular expression patterns
to match sensitive information.
"""
super().__init__()
self.sensitive_patterns = sensitive_patterns
def filter(self, record):
"""
Filters the log record, redacting any matching sensitive information.
"""
message = record.getMessage()
for pattern in self.sensitive_patterns:
message = re.sub(pattern, "<redacted>", message)
record.msg = message
return True
def configure_logging(redis_password=None):
"""
Configures logging with a filter to redact the Redis password if present.
"""
logger = logging.getLogger()
logger.setLevel(logging.INFO) # Or your desired log level
handler = logging.StreamHandler() # Or your desired handler (file, etc.)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
sensitive_patterns = []
if redis_password:
# Create a regex pattern to match the Redis password. Using re.escape is important!
# It handles special characters in the password to prevent regex injection issues.
sensitive_patterns.append(re.compile(re.escape(redis_password)))
sensitive_patterns.append(re.compile(r'redis:\/\/.*:' + re.escape(redis_password) + r'@')) #matches connection strings as well
if sensitive_patterns:
filter = SensitiveDataFilter(sensitive_patterns)
logger.addFilter(filter)
return logger
if __name__ == '__main__':
# Example Usage
redis_pw = "my_secret_redis_password!@#$"
log = configure_logging(redis_pw)
log.info(f"Connecting to Redis with password: {redis_pw}")
log.info(f"Redis connection string: redis://user:{redis_pw}@redis_host:6379")
log.info("This is a normal log message without sensitive data.")
# Showcasing a message without the password provided during configuration
log2 = configure_logging()
log2.info(f"Explicitly logging the password {redis_pw} - THIS IS BAD") # This WILL get logged if not configuredCite this entry
@misc{vaitp:cve20251979,
title = {{Ray <= 2.43.0 logs Redis password, potentially leaking sensitive information.
}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2025},
note = {VAITP Python Vulnerability Dataset, entry CVE-2025-1979},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-1979/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
