Projet

Général

Profil

0001-errors-hide-credentials-in-urls-in-error-messages-34.patch

Lauréline Guérin, 11 octobre 2019 15:13

Télécharger (4,28 ko)

Voir les différences:

Subject: [PATCH] errors: hide credentials in urls in error messages (#34793)

 passerelle/base/models.py | 13 +++++++++++++
 tests/test_proxylogger.py | 41 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)
passerelle/base/models.py
19 19
from django.test import override_settings
20 20
from django.utils.text import slugify
21 21
from django.utils import timezone, six
22
from django.utils.six.moves.urllib.parse import urlparse
22 23
from django.utils.translation import ugettext_lazy as _
23 24
from django.utils.timezone import now
24 25
from django.core.files.base import ContentFile
......
750 751
        if self.connector.down() and not force:
751 752
            # don't log if the connector is known to be down
752 753
            return
754

  
755
        # hide credentials in urls
756
        for url in re.findall(r'(https?://\S+)', message):
757
            try:
758
                parsed = urlparse(url)
759
            except Exception:
760
                continue
761
            if not parsed.username and not parsed.password:
762
                continue
763
            replaced = parsed._replace(netloc="{}:{}@{}".format('***', '***', parsed.hostname))
764
            message = message.replace(url, replaced.geturl())
765

  
753 766
        levelno = getattr(logging, levelname)
754 767
        if self._logger.level <= levelno:
755 768

  
tests/test_proxylogger.py
8 8
from httmock import HTTMock
9 9

  
10 10
from django.core.exceptions import ValidationError
11
from django.utils.log import AdminEmailHandler
11 12

  
12 13
from passerelle.base.models import ProxyLogger, ResourceLog
13 14
from passerelle.apps.feeds.models import Feed
......
24 25
    return connector
25 26

  
26 27

  
28
@pytest.fixture
29
def email_handler():
30
    root = logging.getLogger()
31
    handler = AdminEmailHandler(include_html=True)
32
    handler.level = logging.ERROR
33
    root.handlers.append(handler)
34
    try:
35
        yield
36
    finally:
37
        root.handlers.remove(handler)
38

  
39

  
27 40
def test_proxy_logger_basic(db, connector):
28 41
    pr = ProxyLogger(connector)
29 42
    pr.debug(u'some message')
......
61 74
    pr.debug(u'some message')
62 75
    assert len(ResourceLog.objects.all()) == 0
63 76

  
77

  
64 78
def test_proxy_logger_ignore_when_down(db, connector):
65 79
    with HTTMock(down_mock):  # set connector as down
66 80
        connector.availability()
......
71 85
    assert len(ResourceLog.objects.all()) == 0
72 86

  
73 87

  
88
@pytest.mark.parametrize('error_msg, expected', [
89
    ('Foo Bar', 'Foo Bar'),
90
    ('http://badurl', 'http://badurl'),
91
    ('GET http://tcl.example.net/tclpassagearret (=> 502)',
92
     'GET http://tcl.example.net/tclpassagearret (=> 502)'),
93
    ('GET https://tcl.example.net/tclpassagearret (=> 502)',
94
     'GET https://tcl.example.net/tclpassagearret (=> 502)'),
95
    ('GET http://username:password@tcl.example.net/tclpassagearret (=> 502)',
96
     'GET http://***:***@tcl.example.net/tclpassagearret (=> 502)'),
97
    ('GET https://username:password@tcl.example.net/tclpassagearret (=> 502)',
98
     'GET https://***:***@tcl.example.net/tclpassagearret (=> 502)'),
99
])
100
def test_proxy_logger_hide_url_credentials(db, settings, email_handler, mailoutbox,
101
                                           connector, error_msg, expected):
102
    settings.ADMINS = [('admin', 'admin@example.net')]
103

  
104
    pr = ProxyLogger(connector)
105
    pr.error(error_msg)
106
    assert len(mailoutbox) == 1
107
    msg = mailoutbox[0]
108
    assert msg.to == ['admin@example.net']
109
    assert msg.subject == '[Django] ERROR: %s' % expected
110
    assert expected in msg.body
111
    rl = ResourceLog.objects.latest('pk')
112
    assert rl.message == expected
113

  
114

  
74 115
def test_validate_notification_delays(db, connector):
75 116
    def take(iterator, count):
76 117
        return list(itertools.compress(iterator, range(1, count + 1)))
77
-