Repository navigation
v0.4.2
Corrección: Las imágenes rotas bloqueaban a quien visitaba la página (#1)
La .htaccess de WordPress manda a PHP todo archivo inexistente, así que una imagen o un CSS faltante también termina en un 404 de WordPress, y el rate limit de 404 (10 por minuto por defecto) los contaba igual que a una sonda de rutas. Una página con varios recursos rotos (típico tras una migración) o los apple-touch-icon*.png que pide iOS bastaban para bloquear al visitante durante 15 minutos.
WPS_Loader::should_count_404()(nuevo): los 404 de recursos estáticos (imágenes, CSS, JS, fuentes, source maps) ya no cuentan para el límite. Los de páginas, REST y demás rutas siguen contando.
Seguridad: Los detectores se salteaban agregando una extensión estática a la URL (#2)
Una petición se clasificaba como recurso estático mirando sólo el final de la ruta. /wp-admin/admin-ajax.php/x.css?action=…&id=1 UNION SELECT… ejecuta admin-ajax.php (el resto de la ruta llega como PATH_INFO), pero terminaba en .css: los detectores de SQLi, XSS, path traversal y scanner no la analizaban, y no sumaba al rate limit de páginas. Bastaba ese sufijo para atacar cualquier script PHP del sitio sin que el firewall mirara la petición.
WPS_Request::is_static_path()(nuevo): una ruta que atraviesa un.php/nunca es estática, con cualquier combinación de mayúsculas y también con la barra codificada (%2F). La petición se clasifica según el script que ejecuta (ajax,login,xmlrpc,page) y pasa por todos los detectores.
Seguridad: Los cuerpos JSON no se analizaban (#3)
Los detectores de SQLi, XSS y path traversal sólo recorrían $_POST, que PHP llena únicamente con formularios enviados por POST. Un cuerpo JSON (el formato habitual de la REST API y de muchos plugins) o un formulario enviado con PUT, PATCH o DELETE pasaba sin analizar, y ahí suelen estar las vulnerabilidades de plugins de terceros.
WPS_Request::body_values()(nuevo): reúne los valores string del cuerpo, de$_POST, de cuerpos JSON (application/jsony variantes comoapplication/merge-patch+json) y de formulariosx-www-form-urlencodedenviados con otros métodos. Los tres detectores lo usan en lugar de recorrer$_POSTpor su cuenta.- Límites: se decodifican cuerpos de hasta 1 MB. Un JSON inválido o más grande se analiza como texto (truncado a 1 MB). Se analizan hasta 1000 valores por separado y los sobrantes se juntan en un único texto que también se analiza, así que rellenar con miles de valores basura no alcanza para esconder un payload.
- A tener en cuenta: las peticiones JSON de visitantes sin permisos de edición (por ejemplo, el checkout por la Store API de WooCommerce) se analizan ahora igual que los formularios. Los usuarios con
edit_postssiguen exentos, así que el editor de bloques no se ve afectado.
Seguridad: Fuerza bruta sin límite contra application passwords (#4)
La autenticación Basic de la REST API con application passwords no dispara wp_login_failed sino application_password_failed_authentication, que el detector de login no escuchaba. Se podían probar contraseñas contra /wp-json/ sin que ningún intento se contara ni se bloqueara la IP.
WPS_Login_Detector::on_application_password_failed()(nuevo): cada fallo se registra y se evalúa igual que un login fallido, con el mismo máximo de intentos, bloqueo y escalada. El usuario se toma de la cabecera Basic, como hace WordPress.- Sólo cuentan los intentos reales (contraseña incorrecta, usuario o email inexistente). Los errores por application passwords desactivadas vienen de clientes mal configurados y no se cuentan.
- El evento de login fallido indica ahora el método (
passwordoapplication_password).
Versión
- Versión actualizada a
0.4.2en la cabecera del plugin, la constanteWPS_VERSIONy el MU-plugin.