Sí, este código parece ser vulnerable a una inyección XSS.
¿Qué hace este código?
Comprueba la URL que el usuario escribió para obtener los argumentos GET. Los argumentos GET son todo detrás de un signo de interrogación y son típicos un grupo de pares clave / valor con un signo igual entre ellos separados por &
.
En esta URL de ejemplo
http://example.com/somesite.html?somevar=42&rpath=someothersite.html
el argumento hay dos variables de este tipo. somevar = 42
y rpath = someothersite.html
Su secuencia de comandos buscará un enlace específico en su sitio web, tomará el valor de rpath
y reemplazará el destino del enlace con él. En este ejemplo, ese enlace se cambiaría para apuntar a someothersite.html
.
¿Cómo podría abusarse de esto?
Un enlace en un sitio web no puede simplemente apuntar a otro sitio web. También es posible tener enlaces que comiencen con javascript:
seguido de código javascript. Cuando un usuario hace clic en este enlace, ese código se ejecutará en el contexto del sitio web cargado actualmente.
Eso significa que un atacante podría enviar al usuario un enlace como este:
http://example.com/somesite.html?rpath=javascript:alert('hello world')
Cuando el usuario haga clic en ese enlace y luego en el enlace de redirección de su sitio web, ese código javascript se ejecutará.
¿Por qué esto es un problema?
El sitio web actual puede contener información confidencial. Un javascript ejecutado en el contexto de ese sitio web puede capturar esa información y enviarla a un servidor que controle el atacante.
El script también tiene acceso a las cookies y al usuario localstorage. Cuando usa cookies para rastrear las sesiones de usuario, un atacante podría hacer que el script envíe la cookie de los usuarios a su servidor. Esto podría permitir secuestrar la sesión del usuario y hacerse cargo de su cuenta.
Dependiendo de lo que realmente haga su sitio web, también podría haber muchas otras formas en que un atacante podría causar todo tipo de travesuras al engañar a los usuarios para que ejecuten el código javascript.
¿Cómo podría hacerse mejor?
Poner datos de usuario sin filtrar en un documento HTML siempre es peligroso. En este caso, podría pensar que podría ser suficiente simplemente rechazar cualquier argumento que contenga javascript:
, pero el exploit que se muestra arriba es solo el más obvio. Probablemente hay muchos más sutiles. Tratar de filtrar todo lo que pueda ser malo parece estar más allá de la habilidad de programación del autor del fragmento de código anterior, por lo que aconsejaría no intentarlo. En su lugar, les recomendaría que adopten un enfoque mucho más seguro. En lugar de simplemente colocar cualquier cadena en el sitio web que proporciona el usuario, tenga un conjunto limitado de cadenas posibles para insertar y elija una dependiendo del argumento proporcionado:
switch(redirectPath) {
case 'home':
document.getElementById('redirectpg').href = 'home.php';
break;
case 'about':
document.getElementById('redirectpg').href = 'about.php';
break;
case 'contact':
document.getElementById('redirectpg').href = 'contact.php';
break;
default:
document.getElementById('redirectpg').href = 'index.php';
break;
}