Seguridad
Configuracion de depuracion, proteccion de accesos y endurecimiento del sitio.
Configuracion de depuracion
FlowKit permite gestionar las constantes de depuracion de WordPress directamente desde el panel de administracion, sin necesidad de editar wp-config.php manualmente. Esto facilita activar o desactivar la depuracion segun el entorno de trabajo.
Constantes disponibles
| Constante | Efecto | Valor por defecto |
|---|---|---|
| WP_DEBUG | Activa el modo de depuracion global. WordPress mostrara avisos, advertencias y errores de PHP. | false |
| WP_DEBUG_DISPLAY | Controla si los errores se muestran directamente en pantalla. Si esta desactivado, los errores solo se registran en el archivo de log. | true (cuando WP_DEBUG esta activo) |
| WP_DEBUG_LOG | Registra todos los errores en el archivo wp-content/debug.log. Util para revisar problemas sin exponer mensajes al visitante. |
false |
Recomendaciones por entorno
| Entorno | WP_DEBUG | WP_DEBUG_DISPLAY | WP_DEBUG_LOG |
|---|---|---|---|
| Desarrollo | true |
true |
true |
| Produccion | false |
false |
false |
| Depuracion en produccion | true |
false |
true |
WP_DEBUG_DISPLAY activado en un sitio en produccion. Los mensajes de error pueden revelar rutas del servidor, versiones de PHP y otra informacion sensible a los visitantes.
debug.log sin mostrarse en pantalla. Revisa el archivo periodicamente y eliminalo cuando termines de depurar.
Opciones de proteccion
FlowKit incluye varios modulos de endurecimiento que limitan la superficie de ataque del sitio. Cada opcion se activa de forma independiente desde el panel de seguridad.
Modulos disponibles
- Desactivar WP-JSON — Bloquea el acceso a la API REST de WordPress para usuarios no autenticados. Esto impide que visitantes anonimos consulten endpoints como
/wp-json/wp/v2/users, que pueden revelar nombres de usuario y otra informacion interna. - Desactivar XML-RPC — Elimina el protocolo de acceso remoto
xmlrpc.php. Este protocolo es un vector comun de ataques de fuerza bruta y amplificacion DDoS. La mayoria de sitios modernos no lo necesitan. - Eliminar canales RSS — Desactiva los feeds RSS, Atom y RDF del sitio. Util si no necesitas sindicacion de contenido y prefieres reducir los puntos de acceso publicos.
- Ocultar version de WordPress — Elimina la metaetiqueta
generatordel HTML y otras referencias a la version instalada. Esto dificulta que un atacante identifique la version exacta y busque vulnerabilidades conocidas.
Resumen de opciones
| Opcion | Efecto | Riesgo |
|---|---|---|
| Desactivar WP-JSON | Bloquea la API REST para visitantes anonimos. Los administradores autenticados conservan acceso completo. | Medio — Puede afectar plugins que usen la API REST en el frontend. |
| Desactivar XML-RPC | Desactiva el archivo xmlrpc.php por completo. Elimina un vector de ataques de fuerza bruta. |
Bajo — Solo afecta a clientes XML-RPC (aplicaciones moviles antiguas, Jetpack en modo legacy). |
| Eliminar canales RSS | Devuelve un error 404 para todas las URLs de feeds. | Bajo — Solo afecta a lectores RSS y servicios de sindicacion. |
| Ocultar version | Elimina la metaetiqueta generator y las referencias de version en CSS y scripts. |
Bajo — Sin efectos secundarios conocidos. |
Cifrado de claves
FlowKit almacena las claves de API (como las de servicios de inteligencia artificial) de forma cifrada en la base de datos. En lugar de guardar la clave en texto plano, se utiliza el algoritmo AES-256-CBC para cifrar el valor antes de almacenarlo.
Como funciona
La clase Flowtitude_Helpers proporciona dos metodos estaticos para cifrar y descifrar valores. La clave de cifrado se deriva de las sales de seguridad de WordPress (AUTH_KEY y AUTH_SALT), que son unicas para cada instalacion.
- Cifrado — Antes de guardar una clave de API en
wp_options, se pasa porencrypt(). El resultado es una cadena codificada en base64 que no puede leerse sin la clave de cifrado. - Descifrado — Cuando se necesita usar la clave (por ejemplo, para enviar una peticion a un servicio externo), se recupera el valor cifrado y se pasa por
decrypt().
Ejemplo de uso
// Cifrar antes de guardar
$clave_cifrada = Flowtitude_Helpers::encrypt( $clave_api );
update_option( 'flowtitude_api_key', $clave_cifrada );
// Descifrar cuando se necesite
$clave_cifrada = get_option( 'flowtitude_api_key' );
$clave_original = Flowtitude_Helpers::decrypt( $clave_cifrada );
// Usar la clave para una peticion
$respuesta = wp_remote_post( $endpoint, [
'headers' => [
'Authorization' => 'Bearer ' . $clave_original,
],
] );
AUTH_KEY, AUTH_SALT) deben ser unicas y aleatorias. Si las cambias, los valores cifrados previamente no podran descifrarse. Genera sales seguras desde api.wordpress.org/secret-key.
Ventajas frente al texto plano
- Si un atacante obtiene acceso de lectura a la base de datos, no podra usar las claves de API directamente.
- Las copias de seguridad de la base de datos no contienen claves legibles.
- El cifrado es transparente: el resto del codigo trabaja con los metodos
encrypt()ydecrypt()sin conocer el algoritmo interno.
Verificacion de peticiones
Todas las peticiones AJAX y los formularios del panel de administracion utilizan nonces (numeros de un solo uso) para verificar que la peticion proviene de un usuario legitimo y no de un sitio externo. Esto previene ataques de tipo CSRF (falsificacion de peticiones entre sitios).
Como funciona
WordPress genera un token temporal (nonce) asociado a una accion concreta y al usuario actual. Cuando el navegador envia la peticion, incluye el nonce como parametro. El servidor verifica que el nonce sea valido antes de procesar la solicitud.
- Generacion — Se crea el nonce en PHP con
wp_create_nonce()y se pasa al JavaScript mediantewp_localize_script(). - Envio — El JavaScript incluye el nonce en cada peticion AJAX como parametro
nonceo_wpnonce. - Verificacion — El manejador AJAX del servidor verifica el nonce con
check_ajax_referer()antes de ejecutar cualquier logica.
Ejemplo de implementacion
add_action( 'wp_ajax_flowtitude_guardar_ajustes', 'flowtitude_guardar_ajustes' );
function flowtitude_guardar_ajustes() {
// 1. Verificar nonce — termina con wp_die() si es invalido
check_ajax_referer( 'flowtitude_seguridad', 'nonce' );
// 2. Verificar permisos del usuario
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Permisos insuficientes.' ] );
}
// 3. Sanitizar datos de entrada
$opcion = sanitize_key( $_POST['opcion'] ?? '' );
$valor = sanitize_text_field( $_POST['valor'] ?? '' );
// 4. Procesar la solicitud
update_option( "flowtitude_{$opcion}", $valor );
wp_send_json_success( [ 'message' => 'Ajustes guardados.' ] );
}
Buenas practicas
| Practica | Descripcion |
|---|---|
| Verificar siempre el nonce | Todo manejador AJAX y todo formulario POST debe incluir check_ajax_referer() o wp_verify_nonce() como primera operacion. |
| Verificar permisos del usuario | Despues del nonce, comprobar que el usuario tiene la capacidad necesaria con current_user_can(). Un nonce valido no garantiza que el usuario tenga permiso para esa accion. |
| Sanitizar toda entrada | Usar funciones como sanitize_text_field(), sanitize_key(), absint() o esc_url_raw() para limpiar los datos recibidos antes de procesarlos. |
| Escapar toda salida | Al devolver datos al navegador, usar esc_html(), esc_attr() o wp_kses_post() para prevenir inyeccion de HTML y scripts maliciosos. |
| Nombres de accion unicos | Cada formulario o endpoint AJAX debe usar un nombre de accion distinto para el nonce (por ejemplo, flowtitude_seguridad, flowtitude_recursos). No reutilizar un nonce generico para varias acciones. |
| Nunca confiar en datos del cliente | Los datos enviados desde JavaScript pueden ser manipulados. Valida siempre en el servidor, incluso si ya validaste en el frontend. |
check_ajax_referer() ni current_user_can() permite que cualquier usuario (o un sitio externo) ejecute acciones privilegiadas. Esto es una vulnerabilidad critica.