v1.0.6

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
Importante Nunca dejes 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.
💡 En el modo depuracion en produccion, los errores se registran en 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 generator del HTML y otras referencias a la version instalada. Esto dificulta que un atacante identifique la version exacta y busque vulnerabilidades conocidas.
Posibles conflictos con plugins Algunos plugins dependen de la API REST (WP-JSON) para funcionar correctamente, incluso en el frontend. Si tras desactivar WP-JSON observas errores en formularios de contacto, constructores visuales u otras funcionalidades, reactiva esta opcion y verifica la compatibilidad.

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 por encrypt(). 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

PHP Ejemplo: cifrado y descifrado de claves
// 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,
    ],
] );
🔒 Las sales de seguridad de WordPress (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() y decrypt() 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 mediante wp_localize_script().
  • Envio — El JavaScript incluye el nonce en cada peticion AJAX como parametro nonce o _wpnonce.
  • Verificacion — El manejador AJAX del servidor verifica el nonce con check_ajax_referer() antes de ejecutar cualquier logica.

Ejemplo de implementacion

PHP Manejador AJAX con verificacion completa
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.
No omitas la verificacion Un manejador AJAX sin check_ajax_referer() ni current_user_can() permite que cualquier usuario (o un sitio externo) ejecute acciones privilegiadas. Esto es una vulnerabilidad critica.