@@ -288,3 +288,39 @@ async def test_token_error_handling_refresh_token(
288288 data = refresh_response .json ()
289289 assert data ["error" ] == "invalid_scope"
290290 assert data ["error_description" ] == "The requested scope is invalid"
291+
292+
293+ @pytest .mark .anyio
294+ async def test_registration_rejects_redirect_uri_with_fragment (client : httpx2 .AsyncClient ):
295+ client_data = {
296+ "redirect_uris" : ["https://client.example.com/callback#frag" ],
297+ "token_endpoint_auth_method" : "client_secret_post" ,
298+ "grant_types" : ["authorization_code" , "refresh_token" ],
299+ "response_types" : ["code" ],
300+ "client_name" : "Test Client" ,
301+ }
302+
303+ response = await client .post ("/register" , json = client_data )
304+
305+ assert response .status_code == 400 , response .content
306+ data = response .json ()
307+ assert data ["error" ] == "invalid_redirect_uri"
308+ assert data ["error_description" ] == "Redirect URI must not contain a fragment"
309+
310+
311+ @pytest .mark .anyio
312+ async def test_registration_rejects_non_http_redirect_uri_scheme (client : httpx2 .AsyncClient ):
313+ client_data = {
314+ "redirect_uris" : ["javascript:alert(1)" ],
315+ "token_endpoint_auth_method" : "client_secret_post" ,
316+ "grant_types" : ["authorization_code" , "refresh_token" ],
317+ "response_types" : ["code" ],
318+ "client_name" : "Test Client" ,
319+ }
320+
321+ response = await client .post ("/register" , json = client_data )
322+
323+ assert response .status_code == 400 , response .content
324+ data = response .json ()
325+ assert data ["error" ] == "invalid_redirect_uri"
326+ assert data ["error_description" ] == "Redirect URI must use an HTTP(S) scheme"
0 commit comments