Skip to content

Commit 301c89c

Browse files
miss-islingtonvsajipStanFromIreland
authored
[3.13] gh-94503: Update logging cookbook example with info on addressing log injection. (GH-136446) (GH-136450)
Co-authored-by: Vinay Sajip <[email protected]> Co-authored-by: Stan Ulbrych <[email protected]>
1 parent c44070b commit 301c89c

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

Doc/howto/logging-cookbook.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4127,6 +4127,42 @@ The script, when run, prints something like:
41274127
2025-07-02 13:54:47,234 DEBUG fool me ...
41284128
2025-07-02 13:54:47,234 DEBUG can't get fooled again
41294129
4130+
If, on the other hand, you are concerned about `log injection
4131+
<https://owasp.org/www-community/attacks/Log_Injection>`_, you can use a
4132+
formatter which escapes newlines, as per the following example:
4133+
4134+
.. code-block:: python
4135+
4136+
import logging
4137+
4138+
logger = logging.getLogger(__name__)
4139+
4140+
class EscapingFormatter(logging.Formatter):
4141+
def format(self, record):
4142+
s = super().format(record)
4143+
return s.replace('\n', r'\n')
4144+
4145+
if __name__ == '__main__':
4146+
h = logging.StreamHandler()
4147+
h.setFormatter(EscapingFormatter('%(asctime)s %(levelname)-9s %(message)s'))
4148+
logging.basicConfig(level=logging.DEBUG, handlers = [h])
4149+
logger.debug('Single line')
4150+
logger.debug('Multiple lines:\nfool me once ...')
4151+
logger.debug('Another single line')
4152+
logger.debug('Multiple lines:\n%s', 'fool me ...\ncan\'t get fooled again')
4153+
4154+
You can, of course, use whatever escaping scheme makes the most sense for you.
4155+
The script, when run, should produce output like this:
4156+
4157+
.. code-block:: text
4158+
4159+
2025-07-09 06:47:33,783 DEBUG Single line
4160+
2025-07-09 06:47:33,783 DEBUG Multiple lines:\nfool me once ...
4161+
2025-07-09 06:47:33,783 DEBUG Another single line
4162+
2025-07-09 06:47:33,783 DEBUG Multiple lines:\nfool me ...\ncan't get fooled again
4163+
4164+
Escaping behaviour can't be the stdlib default , as it would break backwards
4165+
compatibility.
41304166

41314167
.. patterns-to-avoid:
41324168

0 commit comments

Comments
 (0)