
Exploit de prueba de concepto para CVE-2025-22963, una vulnerabilidad CSRF en Teedy v1.11 que permite la toma de control de cuentas a través del punto final de cambio de información de usuario.
Vulnerabilidad de falsificación de petición en sitios cruzados (CSRF) en versiones de Teedy <= v1.11 permite a atacantes remotos forzar a un usuario final a cambiar su información de usuario (nombre de usuario, contraseña, etc...) en la aplicación web en la que está autenticado actualmente.
El endpoint de cambio de información de usuario es /api/user/:username.
Este endpoint solo verifica auth_token en las cookies para la autorización.
El valor de auth_token puede ser utilizado desde otros sitios web de origen.
POST /api/user/admin HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded;charset=utf-8
Content-Length: 173
Origin: http://localhost:8080
Connection: keep-alive
Referer: http://localhost:8080/
Cookie: auth_token=890b02eb-3e4b-4134-a523-56093a25952b
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
username=admin&groups=administrators&email=admin%40example.com&totp_enabled=false&storage_quota=0&storage_current=0&disabled=false&password=superSecure&passwordconfirm=superSecure
Por lo tanto, hacer que un usuario final visite el sitio web que envía solicitudes a /api/user/:username provoca que la información del usuario final se cambie a la del atacante remoto.
La información de usuario incluye la contraseña.
Esto podría llevar a una toma de control de la cuenta.
Este ataque es posible cuando un atacante remoto conoce el nombre de usuario de un usuario final.
Este ataque es explotable tanto contra usuarios administradores como invitados.
En esta situación, un atacante puede tomar el control del usuario víctima estableciendo la contraseña del usuario víctima como la contraseña del atacante e iniciando sesión en el usuario víctima con la contraseña del atacante.
Para solucionar esta vulnerabilidad, adjunte un token CSRF al solicitar a /api/user/:username
POST /api/user/admin HTTP/1.1
...
username=admin&groups=administrators&email=admin%40example.com&totp_enabled=false&storage_quota=0&storage_current=0&disabled=false&password=superSecure&passwordconfirm=superSecure&csrf_token=<randomly generated token>
Esto protege contra ataques CSRF porque un atacante no conoce el valor del token CSRF.
Para usar el token CSRF de forma segura, siga estos pasos
Primero, cree estos archivos en el directorio docs/docs-web/src/main/java/com/sismics/docs/rest/util.
package com.sismics.docs.rest.util;
import java.util.Map;
import java.util.HashMap;
import java.security.SecureRandom;
import com.sismics.docs.rest.util.RandomTokenGenerator;
/**
* CSRF Token Class that manages users' CSRF Token
*/
public class CSRFToken {
private static CSRFToken instance = new CSRFToken();
private Map<String, String> tokenMap = new HashMap<String, String>();
private CSRFToken() {}
public static CSRFToken getInstance() {
return instance;
}
public void setToken(String userName, String token) {
tokenMap.put(userName, token);
}
public String getToken(String userName) {
if (tokenMap.containsKey(userName)) {
return tokenMap.get(userName);
}
// avoid using predictable string because bruteforcing this value could lead to bypass CSRF check
return RandomTokenGenerator.generate();
}
public boolean validate(String userName, String token) {
return this.getToken(userName).equals(token);
}
}
RandomTokenGenerator.java
package com.sismics.docs.rest.util;
import java.security.SecureRandom;
import java.lang.StringBuilder;
import java.lang.String;
/**
* A token generator for CSRF Token
*/
public class RandomTokenGenerator {
public static String generate() {
byte[] bytes = new byte[16];
SecureRandom rand = new SecureRandom();
rand.nextBytes(bytes);
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
Después de eso, cambie estos archivos a lo siguiente.

sismics - Teedy(https://github.com/sismics/docs)
portswigger - Falsificación de petición en sitios cruzados (CSRF)(https://portswigger.net/web-security/csrf)
Mozilla - Ejemplos de escenarios de control de acceso(https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#examples_of_access_control_scenarios)
Gracias, Ayato por enseñarme cómo reportar una vulnerabilidad.