CVE-2022-0338 (published 2022-01-25T09:15Z)

Insertion of Sensitive Information into Log File in Conda loguru prior to 0.5.3.\n\n

Severity: MEDIUM
CVSS v2 base score: 4.0 (AV:N/AC:L/Au:S/C:P/I:N/A:N)
CVSS v3 base score: 4.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N)

Weakness information:
cwe_id: CWE-532
cwe_name: Insertion of Sensitive Information into Log File
description: Information written to log files can be of a sensitive nature and give valuable guidance to an attacker or expose sensitive user information.
extended_description: 
            While logging all information may be helpful during development stages, it is important that logging levels be set appropriately before a product ships so that sensitive user data and system information are not accidentally exposed to potential attackers.
            Different log files may be produced and stored for:
            
               Server log files (e.g. server.log).  This can give information on whatever application left the file. Usually this can give full path names and system information, and sometimes usernames and passwords.
               log files that are used for debugging
            
         
         

Fix information:
repo_url: https://github.com/delgan/loguru
commit_details: repo_url: https://github.com/delgan/loguru
author: Delgan
author_date: 2022-01-24 15:34:13+01:00
msg: Document several security considerations and best practices
repository: repo_url: https://github.com/delgan/loguru
repo_name: Delgan/loguru
description: Python logging made (stupidly) simple
repo_language: Python
owner: delgan
file_changes: filename: recipes.rst
change_type: ModificationType.MODIFY
diff: @@ -15,6 +15,7 @@ Code snippets and recipes for ``loguru``
 .. |copy.deepcopy| replace:: :func:`copy.deepcopy`
 .. |os.fork| replace:: :func:`os.fork`
 .. |multiprocessing| replace:: :mod:`multiprocessing`
+.. |pickle| replace:: :mod:`pickle`
 .. |traceback| replace:: :mod:`traceback`
 .. |Thread| replace:: :class:`~threading.Thread`
 .. |Process| replace:: :class:`~multiprocessing.Process`
@@ -47,6 +48,66 @@ Code snippets and recipes for ``loguru``
 .. _`GH#88`: https://github.com/Delgan/loguru/issues/88
 .. _`GH#132`: https://github.com/Delgan/loguru/issues/132
 
+
+Security considerations when using Loguru
+-----------------------------------------
+
+Firstly, if you use |pickle| to load log messages (e.g. from the network), make sure the source is trustable or sign the data to verify its authenticity before deserializing it. If you do not take these precautions, malicious code could be executed by an attacker. You can read more details in this article: `What’s so dangerous about pickles? <https://intoli.com/blog/dangerous-pickles/>`_
+
+.. code::
+
+    import hashlib
+    import hmac
+    import pickle
+
+    def client(connection):
+        data = pickle.dumps("Log message")
+        digest =  hmac.digest(b"secret-shared-key", data, hashlib.sha1)
+        connection.send(digest + b" " + data)
+
+    def server(connection):
+        expected_digest, data = connection.read().split(b" ", 1)
+        data_digest = hmac.digest(b"secret-shared-key", data, hashlib.sha1)
+        if not hmac.compare_digest(data_digest, expected_digest):
+            print("Integrity error")
+        else:
+            message = pickle.loads(data)
+            logger.info(message)
+
+
+You should also avoid logging a message that could be maliciously hand-crafted by an attacker. Calling ``logger.debug(message, value)`` is roughly equivalent to calling ``print(message.format(value))`` and the same safety rules apply. In particular, an attacker could force printing of assumed hidden variables of your application. Here is an article explaining the possible vulnerability: `Be Careful with Python's New-Style String Format <https://lucumr.pocoo.org/2016/12/29/careful-with-str-format/>`_.
+
+.. code::
+
+    SECRET_KEY = 'Y0UC4NTS33Th1S!'
+
+    class SomeValue:
+        def __init__(self, value):
+            self.value = value
+
+    # If user types "{value.__init__.__globals__[SECRET_KEY]}" then the secret key is displayed.
+    message = "[Custom message] " + input()
+    logger.info(message, value=SomeValue(10))
+
+
+Note that by default, Loguru will display the value of existing variables when an ``Exception`` is logged. This is very useful for debugging but could lead to credentials appearing in log files. Make sure to turn it off in production (or set the ``LOGURU_DIAGNOSE=NO`` environment variable).
+
+.. code::
+
+    logger.add("out.log", diagnose=False)
+
+
+Another thing you should consider is to change the access permissions of your log file. Loguru creates files using the built-in |open| function, which means by default they might be read by a different user than the owner. If this is not desirable, be sure to modify the default access rights.
+
+.. code::
+
+    def opener(file, flags):
+        return os.open(file, flags, 0o600)
+
+    logger.add("combined.log", opener=opener)
+
+
+
 Changing the level of an existing handler
 -----------------------------------------
 

programming_language: Markdown
filename: _logger.py
change_type: ModificationType.MODIFY
diff: @@ -199,8 +199,8 @@ class Logger:
 
     Handlers to which the logger sends log messages are added using the |add| method. Note that you
     can use the |Logger| right after import as it comes pre-configured (logs are emitted to
-    |sys.stderr| by default). Messages can be logged with different severity levels and using braces
-    attributes like the |str.format| method do.
+    |sys.stderr| by default). Messages can be logged with different severity levels and they can be
+    formatted using curly braces (it uses |str.format| under the hood).
 
     When a message is logged, a "record" is associated with it. This record is a dict which contains
     information about the logging context: time, function, file, line, thread, level... It also

programming_language: Python