Projet

Général

Profil

0002-idp_oidc-check-length-of-authorize-s-redirect_uri-44.patch

Benjamin Dauvergne, 30 juin 2020 10:57

Télécharger (7,26 ko)

Voir les différences:

Subject: [PATCH 2/3] idp_oidc: check length of authorize's redirect_uri
 (#44589)

 src/authentic2_idp_oidc/app_settings.py |  4 ++
 src/authentic2_idp_oidc/models.py       | 11 +++--
 src/authentic2_idp_oidc/views.py        | 10 +++--
 tests/test_idp_oidc.py                  | 58 +++++++++++++++----------
 4 files changed, 51 insertions(+), 32 deletions(-)
src/authentic2_idp_oidc/app_settings.py
61 61
    def PASSWORD_GRANT_RATELIMIT(self):
62 62
        return self._setting('PASSWORD_GRANT_RATELIMIT', '100/m')
63 63

  
64
    @property
65
    def REDIRECT_URI_MAX_LENGTH(self):
66
        return self._setting('REDIRECT_URI_MAX_LENGTH', 1024)
67

  
64 68
app_settings = AppSettings('A2_IDP_OIDC_')
65 69
app_settings.__name__ = __name__
66 70
sys.modules[__name__] = app_settings
src/authentic2_idp_oidc/models.py
32 32
from authentic2.models import Service
33 33
from authentic2.utils import to_iter
34 34

  
35
from . import utils, managers
35
from . import utils, managers, app_settings
36 36

  
37 37

  
38 38
def generate_uuid():
......
192 192
    def get_wanted_attributes(self):
193 193
        return self.oidcclaim_set.filter(name__isnull=False).values_list('value', flat=True)
194 194

  
195
    def is_valid_redirect_uri(self, redirect_uri):
195
    def validate_redirect_uri(self, redirect_uri):
196
        if len(redirect_uri) > app_settings.REDIRECT_URI_MAX_LENGTH:
197
            raise ValueError('redirect_uri length > %s' % app_settings.REDIRECT_URI_MAX_LENGTH)
198

  
196 199
        parsed_uri = urlparse.urlparse(redirect_uri)
197 200
        for valid_redirect_uri in self.redirect_uris.split():
198 201
            parsed_valid_uri = urlparse.urlparse(valid_redirect_uri)
......
214 217
            else:
215 218
                if parsed_uri.path.rstrip('/') != parsed_valid_uri.path.rstrip('/'):
216 219
                    continue
217
            return True
218
        return False
220
            return
221
        raise ValueError('redirect_uri is not declared')
219 222

  
220 223
    def scope_set(self):
221 224
        return utils.scope_set(self.scope)
src/authentic2_idp_oidc/views.py
141 141
                                   error_description='authz endpoint is configured '
142 142
                                   'for resource owner password credential grant type')
143 143

  
144
    if not client.is_valid_redirect_uri(redirect_uri):
145
        messages.warning(request, _('Authorization request is invalid'))
146
        logger.warning(u'idp_oidc: authorization request error, unknown redirect_uri redirect_uri=%r client_id=%r',
147
                       redirect_uri, client_id)
144
    try:
145
        client.validate_redirect_uri(redirect_uri)
146
    except ValueError as e:
147
        messages.warning(request, _('Authorization request is invalid: %s') % e)
148
        logger.warning(u'idp_oidc: authorization request error, invalid redirect_uri %r (client_id=%r): %s',
149
                       redirect_uri, client_id, e)
148 150
        return redirect(request, 'auth_homepage')
149 151

  
150 152
    fragment = client.authorization_flow == client.FLOW_IMPLICIT
tests/test_idp_oidc.py
1236 1236
    assert user_info['family_name'].endswith(simple_user.last_name)
1237 1237

  
1238 1238

  
1239
def test_client_is_valid_redirect_uri():
1239
def test_client_validate_redirect_uri():
1240 1240
    client = OIDCClient(redirect_uris='''http://example.com
1241 1241
http://example2.com/
1242 1242
http://example3.com/toto
1243 1243
http://*example4.com/
1244 1244
http://example5.com/toto*
1245 1245
''')
1246
    assert client.is_valid_redirect_uri('http://example.com')
1247
    assert client.is_valid_redirect_uri('http://example.com/')
1248
    assert not client.is_valid_redirect_uri('http://coin.example.com/')
1249
    assert not client.is_valid_redirect_uri('http://example.com/toto/')
1250
    assert not client.is_valid_redirect_uri('http://coin.example.com')
1251
    assert client.is_valid_redirect_uri('http://example2.com')
1252
    assert client.is_valid_redirect_uri('http://example2.com/')
1253
    assert not client.is_valid_redirect_uri('http://example3.com/')
1254
    assert not client.is_valid_redirect_uri('http://example3.com')
1255
    assert client.is_valid_redirect_uri('http://example3.com/toto')
1256
    assert client.is_valid_redirect_uri('http://example3.com/toto/')
1257
    assert client.is_valid_redirect_uri('http://example4.com/')
1258
    assert client.is_valid_redirect_uri('http://example4.com')
1259
    assert client.is_valid_redirect_uri('http://coin.example4.com')
1260
    assert client.is_valid_redirect_uri('http://coin.example4.com/')
1261
    assert not client.is_valid_redirect_uri('http://coinexample4.com')
1262
    assert not client.is_valid_redirect_uri('http://coinexample4.com/')
1263
    assert client.is_valid_redirect_uri('http://example5.com/toto')
1264
    assert client.is_valid_redirect_uri('http://example5.com/toto/')
1265
    assert client.is_valid_redirect_uri('http://example5.com/toto/tata')
1266
    assert client.is_valid_redirect_uri('http://example5.com/toto/tata/')
1267
    assert not client.is_valid_redirect_uri('http://example5.com/tototata/')
1268
    assert not client.is_valid_redirect_uri('http://example5.com/tototata')
1246
    # ok
1247
    for uri in [
1248
            'http://example.com',
1249
            'http://example.com/',
1250
            'http://example2.com',
1251
            'http://example2.com/',
1252
            'http://example3.com/toto',
1253
            'http://example3.com/toto/',
1254
            'http://example4.com/',
1255
            'http://example4.com',
1256
            'http://coin.example4.com',
1257
            'http://coin.example4.com/',
1258
            'http://example5.com/toto',
1259
            'http://example5.com/toto/',
1260
            'http://example5.com/toto/tata',
1261
            'http://example5.com/toto/tata/']:
1262
        client.validate_redirect_uri(uri)
1263
    # nok
1264
    for uri in [
1265
            'http://coin.example.com/',
1266
            'http://example.com/toto/',
1267
            'http://coin.example.com',
1268
            'http://example3.com/',
1269
            'http://example3.com',
1270
            'http://coinexample4.com',
1271
            'http://coinexample4.com/',
1272
            'http://example5.com/tototata/',
1273
            'http://example5.com/tototata']:
1274
        with pytest.raises(ValueError, match=r'is not declared'):
1275
            client.validate_redirect_uri(uri)
1276
    client.validate_redirect_uri('http://example5.com/toto/' + 'a' * 500)
1277
    with pytest.raises(ValueError, match=r'redirect_uri length >'):
1278
        client.validate_redirect_uri('http://example5.com/toto/' + 'a' * 1024)
1269 1279

  
1270 1280

  
1271 1281
def test_filter_api_users(app, oidc_client, admin, simple_user, role_random):
1272
-