Projet

Général

Profil

0001-utils-use-same_origin-from-authentic2-69740.patch

Benjamin Dauvergne, 30 septembre 2022 08:18

Télécharger (3,62 ko)

Voir les différences:

Subject: [PATCH 1/2] utils: use same_origin() from authentic2 (#69740)

 mellon/utils.py | 59 ++++++++++++++++++++++++++++++++++++++++++++-----
 mellon/views.py |  4 ++--
 2 files changed, 56 insertions(+), 7 deletions(-)
mellon/utils.py
245 245
    return '\x00' not in s
246 246

  
247 247

  
248
PROTOCOLS_TO_PORT = {
249
    'http': '80',
250
    'https': '443',
251
}
252

  
253

  
254
def netloc_to_host_port(netloc):
255
    if not netloc:
256
        return None, None
257
    splitted = netloc.split(':', 1)
258
    if len(splitted) > 1:
259
        return splitted[0], splitted[1]
260
    return splitted[0], None
261

  
262

  
263
def same_domain(domain1, domain2):
264
    if domain1 == domain2:
265
        return True
266

  
267
    if not domain1 or not domain2:
268
        return False
269

  
270
    if domain2.startswith('.'):
271
        # p1 is a sub-domain or the base domain
272
        if domain1.endswith(domain2) or domain1 == domain2[1:]:
273
            return True
274
    return False
275

  
276

  
248 277
def same_origin(url1, url2):
249
    """
250
    Checks if two URLs are 'same-origin'
278
    """Checks if both URL use the same domain. It understands domain patterns on url2, i.e. .example.com
279
    matches www.example.com.
280

  
281
    If not scheme is given in url2, scheme compare is skipped.
282
    If not scheme and not port are given, port compare is skipped.
283
    The last two rules allow authorizing complete domains easily.
251 284
    """
252 285
    p1, p2 = urlparse(url1), urlparse(url2)
253
    if url1.startswith('/') or url2.startswith('/'):
286
    p1_host, p1_port = netloc_to_host_port(p1.netloc)
287
    p2_host, p2_port = netloc_to_host_port(p2.netloc)
288

  
289
    # url2 is relative, always same domain
290
    if url2.startswith('/') and not url2.startswith('//'):
254 291
        return True
292

  
293
    if p2.scheme and p1.scheme != p2.scheme:
294
        return False
295

  
296
    if not same_domain(p1_host, p2_host):
297
        return False
298

  
255 299
    try:
256
        return (p1.scheme, p1.hostname, p1.port) == (p2.scheme, p2.hostname, p2.port)
257
    except ValueError:
300
        if (p2_port or (p1_port and p2.scheme)) and (
301
            (p1_port or PROTOCOLS_TO_PORT[p1.scheme]) != (p2_port or PROTOCOLS_TO_PORT[p2.scheme])
302
        ):
303
            return False
304
    except (ValueError, KeyError):
258 305
        return False
259 306

  
307
    return True
308

  
260 309

  
261 310
def get_status_codes_and_message(profile):
262 311
    assert profile, 'missing lasso.Profile'
mellon/views.py
84 84
    except UnicodeError:
85 85
        log.warning('next parameter ignored, as is\'s not an ASCII string')
86 86
        return
87
    if not utils.same_origin(next_url, request.build_absolute_uri()):
87
    if not utils.same_origin(request.build_absolute_uri(), next_url):
88 88
        log.warning('next parameter ignored as it is not of the same origin')
89 89
        return
90 90
    return next_url
......
725 725
        '''Launch a logout request to the identity provider'''
726 726
        next_url = request.GET.get(REDIRECT_FIELD_NAME)
727 727
        referer = request.headers.get('Referer')
728
        if not referer or utils.same_origin(referer, request.build_absolute_uri()):
728
        if not referer or utils.same_origin(request.build_absolute_uri(), referer):
729 729
            if hasattr(request, 'user') and request.user.is_authenticated:
730 730
                logout = None
731 731
                try:
732
-