mu-plugins: versionar los dos que solo vivian en produccion

Preparando el cutover a Hetzner (#180), el criterio de migracion limpia
(#180 comment-516) dice recrear los mu-plugins desde el repo. Comparados por
MD5 los 26 comunes coinciden byte a byte, pero estos dos estaban vivos en
produccion y en ninguna rama del repo:

- fea-security-blocked-users.php: es la contencion del incidente #183
  (comment-437). Bloquea wp_authenticate_user y allow_password_reset para
  los IDs 1047 (pabloarias), 1049 (josek) y 1087 (andrey). Sin este fichero,
  recrear "los fea-* desde el repo" habria revivido las tres cuentas en el
  servidor nuevo, porque sus hashes viajan dentro del dump.
- fea-subir-avatar-api.php: endpoint REST del #175.

Copiados por HTTP-less cat sobre SSH y verificados por sha256 contra el
origen; php -l limpio en ambos.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 16:56:49 -04:00
parent 69e849d38e
commit 91a212250d
2 changed files with 274 additions and 0 deletions
@@ -0,0 +1,27 @@
<?php
/**
* Plugin Name: FEA Security — disabled legacy accounts
* Description: Blocks authentication and password resets for accounts disabled during incident #183.
* Version: 1.0.0
*/
declare(strict_types=1);
const FEA_SECURITY_DISABLED_USER_IDS = [1047, 1049, 1087];
function fea_security_is_disabled_user(int $user_id): bool
{
return in_array($user_id, FEA_SECURITY_DISABLED_USER_IDS, true);
}
add_filter('wp_authenticate_user', static function (WP_User $user): WP_User|WP_Error {
if (fea_security_is_disabled_user((int) $user->ID)) {
return new WP_Error('fea_account_disabled', __('This account is disabled.'));
}
return $user;
}, 99);
add_filter('allow_password_reset', static function (bool $allow, int $user_id): bool {
return fea_security_is_disabled_user($user_id) ? false : $allow;
}, 99, 2);