]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-94503: Update logging cookbook example with info on addressing log injection....
authorVinay Sajip <vinay_sajip@yahoo.co.uk>
Wed, 9 Jul 2025 07:30:56 +0000 (08:30 +0100)
committerGitHub <noreply@github.com>
Wed, 9 Jul 2025 07:30:56 +0000 (08:30 +0100)
Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
Doc/howto/logging-cookbook.rst

index ae2697fbce30add90534c7e2bdcb8dddf6c95e18..52537a91df542c1996a0cb0f6a76ae50a088db18 100644 (file)
@@ -4140,6 +4140,42 @@ The script, when run, prints something like:
     2025-07-02 13:54:47,234 DEBUG     fool me ...
     2025-07-02 13:54:47,234 DEBUG     can't get fooled again
 
+If, on the other hand, you are concerned about `log injection
+<https://owasp.org/www-community/attacks/Log_Injection>`_, you can use a
+formatter which escapes newlines, as per the following example:
+
+.. code-block:: python
+
+    import logging
+
+    logger = logging.getLogger(__name__)
+
+    class EscapingFormatter(logging.Formatter):
+        def format(self, record):
+            s = super().format(record)
+            return s.replace('\n', r'\n')
+
+    if __name__ == '__main__':
+        h = logging.StreamHandler()
+        h.setFormatter(EscapingFormatter('%(asctime)s %(levelname)-9s %(message)s'))
+        logging.basicConfig(level=logging.DEBUG, handlers = [h])
+        logger.debug('Single line')
+        logger.debug('Multiple lines:\nfool me once ...')
+        logger.debug('Another single line')
+        logger.debug('Multiple lines:\n%s', 'fool me ...\ncan\'t get fooled again')
+
+You can, of course, use whatever escaping scheme makes the most sense for you.
+The script, when run, should produce output like this:
+
+.. code-block:: text
+
+    2025-07-09 06:47:33,783 DEBUG     Single line
+    2025-07-09 06:47:33,783 DEBUG     Multiple lines:\nfool me once ...
+    2025-07-09 06:47:33,783 DEBUG     Another single line
+    2025-07-09 06:47:33,783 DEBUG     Multiple lines:\nfool me ...\ncan't get fooled again
+
+Escaping behaviour can't be the stdlib default , as it would break backwards
+compatibility.
 
 .. patterns-to-avoid: