Hardcodificar claves API en functions.php de WordPress es una de las prácticas inseguras más comunes y evitables que existen. Cuando guardás credenciales directamente en el código, cualquier atacante que acceda al archivo — por un plugin comprometido, un backup expuesto o un repositorio mal configurado — tiene acceso completo a tu cuenta de WooCommerce, tus pagos, y los datos de tus clientes.

En 30 segundos

  • Guardar claves API o secretos HMAC directamente en functions.php expone tus credenciales a cualquier atacante con acceso al sistema de archivos o al historial de Git.
  • Una vulnerabilidad crítica en WooCommerce Payments afectó en 2023 a más de 500.000 sitios — ese es el tipo de daño que una sola credencial comprometida puede provocar.
  • Las alternativas seguras son: variables de entorno (.env), wp-config.php (con precauciones), o servicios de gestión de secretos para entornos enterprise.
  • Después de migrar las claves, siempre generá nuevas credenciales — asumir que las viejas estuvieron expuestas es la única postura razonable.
  • El riesgo no es solo teórico: CVE-2008-1930 documentó exactamente esto con cookies HMAC hardcodeadas en WordPress.

WooCommerce es un plugin para WordPress desarrollado por Automattic que convierte un sitio en tienda de comercio electrónico. Gestiona productos, pagos, inventario y envíos.

Qué es el hardcoding de claves API y por qué es crítico

El hardcoding es escribir un valor sensible directamente en el código fuente en lugar de leerlo desde una fuente externa segura. En el caso de WordPress, se ve así:

define('MI_API_KEY', 'sk_live_abc123secreto');
$signature = hash_hmac('sha256', $payload, 'mi_secreto_hmac_fijo');

El problema no es solo dónde está ese string. Es que ese string ahora vive en tu repositorio de Git, en tus backups, en cualquier exportación del tema, en el panel de edición de temas de WordPress, y en los archivos que tu hosting guarda por su cuenta. Cada uno de esos lugares es un vector de ataque.

Hardcodificar claves API en functions.php es, específicamente, guardar credenciales en el archivo de funciones del tema activo de WordPress. Este archivo se ejecuta en cada request, es editable desde el panel de administración (Apariencia > Editor de temas), y muchos desarrolladores lo agregan sin pensarlo dos veces a su repositorio de control de versiones.

Según datos de 2025, cerca del 40% de los ataques exitosos en WordPress involucran configuraciones inseguras o credenciales expuestas, no vulnerabilidades zero-day. O sea, el vector más común no es una falla sofisticada: es descuido.

Riesgos específicos de guardar credenciales en functions.php

Ponele que tu tienda WooCommerce tiene integrada una pasarela de pago con su API key en functions.php. ¿Qué puede pasar? Para más detalles técnicos, mirá cuando integras APIs externas en WooCommerce.

Primero, si un plugin comprometido tiene acceso de lectura al sistema de archivos (algo común en ataques a WordPress), puede leer ese archivo y exfiltrar la clave. Segundo, si usás Git y en algún momento subiste ese archivo al repositorio sin excluirlo del .gitignore, la clave está en el historial para siempre. Incluso si la borrás en el commit siguiente, cualquiera con acceso al repo puede hacer git log -p y verla.

Tercero, y esto es lo que menos se menciona: si alguien obtiene acceso admin a tu WordPress, puede leer functions.php directamente desde el panel. No necesita SSH, no necesita FTP. Con las credenciales de un admin comprometido alcanza.

El antecedente más citado en la literatura de seguridad sobre este tema es CVE-2008-1930, que documentó el riesgo de cookies HMAC con secretos hardcodeados en WordPress. La vulnerabilidad permitía a un atacante predecir el valor del cookie de autenticación y escalar privilegios. El problema de raíz era siempre el mismo: un secreto fijo en el código.

Impacto de credenciales comprometidas en tiendas WooCommerce

En marzo de 2023, The Hacker News reportó una vulnerabilidad crítica en WooCommerce Payments (CVE-2023-28121) que afectó más de 500.000 sitios. El fallo permitía a atacantes sin autenticación escalar privilegios hasta nivel administrador. Si en alguno de esos sitios las claves API de la pasarela de pago estaban hardcodeadas, el daño potencial no era solo acceso al panel: era acceso completo a transacciones, datos de tarjetas tokenizadas, información de clientes, y en muchos casos la posibilidad de iniciar reembolsos o modificar precios.

¿Qué puede hacer un atacante con una API key de WooCommerce comprometida? Según la documentación oficial de autenticación de la REST API de WooCommerce, las claves tienen alcance configurable: lectura, escritura o lectura/escritura. Una clave con permisos de escritura permite crear, modificar y eliminar productos, órdenes y clientes. No hace falta explicar cuánto vale eso para un atacante.

functions.php vs wp-config.php vs soluciones modernas

No todos los métodos de almacenamiento de credenciales son igual de malos. Acá viene la tabla que muchos sitios no muestran:

MétodoSeguridadRiesgo GitAccesible desde panel WPRecomendado
Hardcoded en functions.phpPésimaMuy altoSí (editor de temas)No
Hardcoded en wp-config.phpMalaAlto si se sube al repoNo (fuera del webroot)Solo como fallback
Variables de entorno (.env)BuenaNinguno si .gitignore correctoNoSí, para la mayoría
Secrets Manager (AWS/Vault)ExcelenteNingunoNoSí, para enterprise
Plugins de gestión de keysVariableBajoSí (si el plugin lo permite)Con cuidado
hardcodificar claves api functions.php diagrama explicativo

functions.php es lo peor porque combina todos los problemas: se ejecuta en cada request (si algo falla, rompe el sitio entero), es editable desde el dashboard, y la mayoría de los desarrolladores lo agregan al repositorio sin pensarlo. wp-config.php es mejor porque está fuera del webroot y WordPress lo excluye de las rutas web, pero sigue siendo un archivo de código que puede terminar en Git.

Variables de entorno y archivos .env: la forma segura

La solución más accesible para la mayoría de los sitios WordPress es usar un archivo .env combinado con la librería vlucas/phpdotenv. El flujo es simple.

Creás un archivo .env en la raíz del proyecto con permisos 600 (solo lectura/escritura para el propietario): Sobre eso hablamos en compara diferentes enfoques de seguridad.

WC_API_KEY=ck_abc123...
WC_API_SECRET=cs_xyz456...
HMAC_SECRET=mi_secreto_para_firmar

Ese archivo va en .gitignore. Siempre. Sin excepción. Junto a .env.example (sin valores reales) para que otros desarrolladores sepan qué variables configurar.

Después instalás phpdotenv via Composer y lo cargás en wp-config.php antes de las configuraciones de base de datos:

require_once __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

En tu código, en lugar de la clave hardcodeada, usás:

$api_key = getenv('WC_API_KEY');
$signature = hash_hmac('sha256', $payload, getenv('HMAC_SECRET'));

Esto es lo que recomiendan los desarrolladores de WordPress con experiencia en producción: separar la configuración del código. Las credenciales no se almacenan en el repositorio ni en la base de datos, y cada entorno (local, staging, producción) tiene su propio .env con sus propias claves.

Servicios de almacenamiento de secretos para proyectos enterprise

Si tu sitio maneja volúmenes altos o tiene múltiples ambientes con equipos distintos, los archivos .env tienen un límite: alguien tiene que distribuir las claves por algún canal, y ese canal puede ser inseguro.

Para esos casos existe AWS Secrets Manager, HashiCorp Vault, o Google Secret Manager. Las ventajas concretas: encriptación en tránsito y en reposo, rotación automática de credenciales, auditoría de accesos, y control granular de permisos (cada servicio accede solo a las claves que necesita, no a todas). Según la documentación de Pantheon sobre gestión de secretos en WordPress, la recomendación para proyectos de escala enterprise es usar una capa de gestión dedicada y no depender de archivos de entorno en el servidor.

Para un blog o tienda mediana, esto probablemente sea sobredimensionado. Para una plataforma de e-commerce con decenas de miles de transacciones mensuales, es la línea base mínima.

Guía paso a paso: migrar claves hardcodeadas a variables de entorno

Si ahora mismo tenés credenciales en functions.php, seguí este orden exacto. No al revés.

  • Paso 1: Crear el archivo .env. Localmente primero. Copiá las claves actuales a ese archivo con el formato CLAVE=valor.
  • Paso 2: Instalar phpdotenv. composer require vlucas/phpdotenv en la raíz del proyecto.
  • Paso 3: Cargar el .env en wp-config.php. Antes de cualquier define(), cargás el dotenv con el fragmento del punto anterior.
  • Paso 4: Reemplazar los strings hardcodeados. Buscá todas las ocurrencias de las claves en el código y cambiálas por getenv('NOMBRE_VARIABLE').
  • Paso 5: Probar en local. Verificá que el sitio funciona correctamente antes de tocar producción.
  • Paso 6: Generar claves nuevas. En WooCommerce, en tu panel de pasarela de pago, generá credenciales nuevas. Asumí que las anteriores están comprometidas.
  • Paso 7: Subir el .env al servidor de producción. Por SFTP o SSH, nunca por Git. Verificar permisos 600.
  • Paso 8: Revocar las claves viejas. No cuando te acuerdes. Ahora.

¿Y si la clave ya estuvo en un repo público? Tomalo como comprometida sin importar cuánto tiempo estuvo ahí. Ya lo cubrimos antes en soluciones profesionales para proteger credenciales.

Mejores prácticas: rotación, auditoría y permisos mínimos

Sacar las claves del código es el primer paso, no el último.

Creá claves separadas por entorno. La clave de desarrollo no debe funcionar en producción. Si se expone la de staging, el daño está contenido. Establecé una rotación periódica: cada 90 días es un estándar razonable para la mayoría de los proyectos, aunque idealmente lo hacés cuando cambia alguien del equipo o cuando hay cualquier sospecha de exposición.

Sobre permisos: la guía oficial de mejores prácticas de seguridad de WooCommerce recomienda el principio de least privilege. Si una integración solo necesita leer órdenes, su clave no debería tener permisos de escritura. Si una clave está inactiva más de 30 días, revocala.

Monitoreá los logs de la API. Si ves requests que no reconocés, es probable que alguien más tenga acceso. Para eso sirven las claves separadas: si una se usa de forma anómala, podés revocarla sin afectar el resto del sistema.

Para hosting de sitios WordPress en producción, elegí proveedores que ofrezcan SFTP, sin FTP plano, con separación de usuarios por sitio. donweb.com tiene planes de hosting WordPress con acceso seguro y soporte para configuraciones de entorno — algo que no todos los proveedores ofrecen en la región.

Errores comunes al gestionar claves API en WordPress

Error 1: Crear el .env y de todas formas dejarlo en el repositorio. Pasa más seguido de lo que parece. Se agrega el archivo, se hace el commit antes de actualizar el .gitignore, y queda registrado en el historial. La regla: primero el .gitignore, después el archivo. Siempre.

Error 2: Migrar las claves pero no generar nuevas. Si las claves estuvieron hardcodeadas y ahora están en un .env, eso no borra el historial de dónde estuvieron antes. La migración técnica sin rotación de claves es la mitad del trabajo (spoiler: la mitad menos importante).

Error 3: Usar la misma clave en todos los entornos. Muchos desarrolladores usan credenciales de producción en local porque «es más fácil». El resultado es que si el entorno de desarrollo se compromete, producción también cae.

Error 4: Pensar que wp-config.php es automáticamente seguro. Está fuera del webroot, sí. Pero si lo subís al repositorio sin excluirlo, el riesgo es exactamente el mismo que functions.php. Y en muchos proyectos heredados, wp-config.php tiene la contraseña de la base de datos, las claves de las salt, y las credenciales de la API todo junto. Un archivo, muchos problemas. Esto se conecta con lo que analizamos en herramientas especializadas en seguridad WordPress.

Preguntas Frecuentes

¿Qué pasa si guardé una clave API en functions.php de WordPress?

Asumí que la clave está comprometida. Generá una nueva inmediatamente desde el panel de WooCommerce o el servicio correspondiente, y revocá la anterior. Después migrá a variables de entorno antes de volver a poner credenciales en cualquier archivo de código.

¿Cuál es la diferencia entre guardar claves en functions.php y en wp-config.php?

wp-config.php está fuera del webroot por defecto, lo que evita que sea accesible directamente desde el navegador. functions.php es editable desde el panel de WordPress si hay acceso admin. Ninguno es recomendable para credenciales sensibles, pero wp-config.php presenta menos superficie de ataque. La opción correcta es variables de entorno.

¿Cómo puedo proteger mis claves API de WooCommerce?

Usá variables de entorno con un archivo .env excluido del repositorio, con permisos 600 en el servidor. Generá claves separadas por entorno (local, staging, producción). Habilitá solo los permisos necesarios (lectura o escritura, no ambos si no hace falta). Rotá las claves periódicamente y revocá las que no uses.

¿Debería usar variables de entorno en lugar de hardcoding para mis secretos?

Sí. Las variables de entorno separan la configuración del código, permiten usar credenciales distintas por entorno, y no se almacenan en el repositorio ni en la base de datos. Con vlucas/phpdotenv la integración en WordPress lleva menos de 15 minutos. No hay argumento válido para hardcodear en 2026.

¿Qué es un secreto HMAC hardcodeado y por qué es peligroso?

Un secreto HMAC es la clave que usás para firmar mensajes y verificar su autenticidad. Si ese secreto está fijo en el código, cualquier atacante que lo lea puede forjar firmas válidas, saltear verificaciones de autenticidad, o replicar requests autenticados. CVE-2008-1930 documentó exactamente este vector en WordPress: secretos de cookies fijos que permitían escalar privilegios.

Conclusión

Hardcodificar claves API en functions.php no es un error menor de configuración. Es dejar la llave de la caja registradora pegada en la puerta del local. La migración a variables de entorno es técnicamente simple, lleva menos de una hora en cualquier proyecto WordPress estándar, y elimina uno de los vectores de ataque más frecuentes en la plataforma.

Si te encontrás con credenciales hardcodeadas en un proyecto que ya está en producción, el orden es: generá claves nuevas primero, migrá al sistema seguro después. Al revés no funciona. Y si el proyecto tiene Git, revisá el historial completo: git log -p --all -- functions.php te va a mostrar todo lo que alguna vez estuvo ahí.

Fuentes

Categorizado en: