XUT_ / COURSES / PENETRATION TESTER

Sensitive Information Disclosure

Divulgación de Información Sensible

El primer problema común que veremos será la exposición de información en el JWT.

Un acercamiento de manejo de sesiones basado en cookies usa la sesión del lado del servidor para guardar múltiples parámetros. En PHP, por ejemplo, puedes usar $SESSION['var']=data para guardar un valor asociado con la sesión de un usuario. Estos valores no se exponen del lado del cliente y por ello sólo pueden ser recuperados del lado del servidor. Sin embargo, con los tokens, las afirmaciones son expuestas ya que el JWT entero se manda al lado del cliente. Algunos ejemplos serían:

  • Divulgación de credenciales en hash, o pero, en texto claro si la contraseña se manda como afirmación.
  • Exposición de información de la red interna como IP privada o hostname del servidor de autentificación.

Ejemplo práctico 1

Vamos a autentificarnos en nuestra API con la siguiente petición cURL:

curl -H 'Content-Type: application/json' -X POST -d '{ "username" : "user", "password" : "password1" }' http://10.80.190.89/api/v1.0/example1

Esto nos devuelve un JWT token.

Sensitive Information Disclosure

Una vez lo tenemos, decodeamos el body del JWT para ver información sensible. Puedes hacerlo manualmente o usar JWT.io para hacerlo.

Sensitive Information Disclosure

El Error de Desarrollo

En el ejemplo, la información sensible fue añadida a las afirmaciones, como se muestra debajo.

python
payload = {
    "username" : username,
    "password" : password,
    "admin" : 0,
    "flag" : "[redacted]"
}

access_token = jwt.encode(payload, self.secret, algorithm="HS256")
El Arreglo

Valores como la contraseña o la flag no deberían ser añadidas a los claims (afirmaciones) ya que el JWT será mandado al cliente. En su lugar, estos valores deberían guardarse de forma segura en el backend del servidor. Al ser requeridos, el nombre de usuario puede ser leído de un JWT verificado y usado para comprobar el valor de la flag/contraseña.

python
payload = jwt.decode(token, self.secret, algorithms="HS256")

username = payload['username']
flag = self.db_lookup(username, "flag")