Seguridad en Oracle APEX: Estrategias para evitar inyecciones SQL y ataques XSS
La importancia de la seguridad para lograr excelencia en Oracle APEX

En nuestra entrada anterior de APEX Insights, cubrimos las diez recomendaciones clave para construir aplicaciones APEX robustas y mantenibles. Ahora, es momento de profundizar en el pilar más crítico de todos: la seguridad.
Oracle APEX ofrece una arquitectura excepcionalmente segura por diseño, pero el código PL/SQL y JavaScript que escribimos puede introducir vulnerabilidades. Los dos ataques más comunes que enfrentaremos son la Inyección SQL (un ataque del lado del servidor) y el Cross-Site Scripting (XSS) (un ataque del lado del cliente).
Dominar las defensas contra estos ataques es el paso definitivo para llevar tus aplicaciones APEX a un nivel de clase mundial.
El Enemigo del Servidor: Inyección SQL
La Inyección SQL ocurre cuando un atacante introduce código SQL malicioso a través de una entrada de usuario, haciendo que el servidor ejecute comandos no deseados (ej. borrar datos, obtener información confidencial).
La Regla de Oro: Siempre Variables de Enlace (Bind Variables)
La defensa es simple y absoluta: Nunca concatenes entradas de usuario directamente para construir una sentencia SQL. Siempre utiliza variables de enlace (:PXX_ITEM) que fuerzan a la base de datos a tratar la entrada como datos, y no como código.
Si aún usas concatenación en PL/SQL, ¡este es tu recordatorio final! Detente y refactoriza hoy mismo.
Práctica Deficiente (VULNERABLE)
DECLARE
l_user_id VARCHAR2(50) := :P1_USER_ID;
BEGIN
-- El atacante puede inyectar: ' OR 1=1 --
EXECUTE IMMEDIATE 'UPDATE users SET status = ''ACTIVE'' WHERE user_id = ''' || l_user_id || '''';
END;
Práctica Recomendada (SEGURO)
BEGIN
-- APEX y la BD manejan el valor de :P1_USER_ID como un dato seguro.
UPDATE users SET status = 'ACTIVE' WHERE user_id = :P1_USER_ID;
END;
-- Para SQL dinámico, usa la API de APEX (APEX_EXEC).
APEX_EXEC.EXECUTE_SQL(
p_sql_statement => 'UPDATE users SET status = :P_STATUS WHERE user_id = :P_USER_ID',
p_bind_vars => APEX_EXEC.T_BIND_VAR(
APEX_EXEC.T_BIND_VAR_ROW('P_STATUS', 'ACTIVE'),
APEX_EXEC.T_BIND_VAR_ROW('P_USER_ID', :P1_USER_ID)
)
);
El Enemigo del Cliente: Cross-Site Scripting (XSS)
El XSS ocurre cuando el código malicioso (generalmente JavaScript) se inyecta en la página web a través de un campo de entrada y se ejecuta en el navegador de otro usuario. Esto permite robar cookies de sesión o redirigir al usuario.
La Solución Declarativa: Escapar Caracteres Especiales
APEX nos ofrece la defensa más poderosa contra XSS de forma declarativa. La regla es: Siempre que muestres un valor ingresado por el usuario, debes "escapar" su contenido.
En Items de Página: Utiliza el tipo de ítem adecuado. Si es solo texto, nunca uses un tipo que interprete HTML (como Rich Text Editor) si el contenido no es confiable.
En Reportes (Clásicos o Interactivos): Asegúrate de que la configuración de la columna tenga marcada la opción: "Escape special characters" (Escapar caracteres especiales).

La Solución PL/SQL: La Función APEX_ESCAPE.HTML_OUT
Si estás generando código HTML en PL/SQL (por ejemplo, para un htp.p o en una función que devuelve un valor para ser mostrado), siempre debes sanear el contenido usando la API de APEX.
Práctica Deficiente (VULNERABLE)
-- MAL: No sanea el contenido, vulnerable a XSS
htp.p('Bienvenido, ' || :P1_USUARIO_NOMBRE);
Práctica Recomendada (SEGURO)
-- BIEN: Sanea la salida antes de enviarla al navegador
htp.p('Bienvenido, ' || APEX_ESCAPE.HTML_OUT(:P1_USUARIO_NOMBRE));
Seguridad en el Flujo y Llamadas AJAX
La seguridad no termina en el código SQL; también se aplica a cómo navegas y ejecutas procesos en segundo plano.
Uso Obligatorio de apex.server.process() para AJAX
Si tu código JavaScript necesita ejecutar un Proceso de Aplicación (AJAX) en el servidor, nunca intentes construir la llamada manualmente. Siempre utiliza la función apex.server.process() o apex.ajax.run() de la API de JavaScript de APEX.
- ¿Por qué? Estas funciones se encargan automáticamente de pasar el checksum de la sesión y otros valores de seguridad, asegurando que la llamada sea legítima y provenga de una sesión válida.
// Ejecución de un Proceso de Aplicación (AJAX)
// SIEMPRE usa apex.server.process() para enviar el checksum de seguridad
// 1. Definir los ítems de página a enviar al servidor
const items_a_enviar = {
// Usamos $v() o apex.item().getValue() para obtener los valores del DOM de forma segura
x01: $v('P1_NUEVO_VALOR'),
f01: ['valor1', 'valor2'] // Envío de arrays de datos
};
// 2. Llamada segura al Process "PROCESO_GUARDAR_DATOS"
apex.server.process(
"PROCESO_GUARDAR_DATOS", // Nombre del Process APEX definido en Shared Components
{
dataType: "json", // Tipo de datos esperado en la respuesta
x01: items_a_enviar.x01,
f01: items_a_enviar.f01
},
{
success: function(pData) {
// Manejar la respuesta exitosa del servidor
if (pData.success) {
apex.message.showPageSuccess('Datos guardados exitosamente.');
}
},
error: function(jqXHR, textStatus, errorThrown) {
// Manejar errores
apex.message.clearErrors();
apex.message.showErrors([{
type: "error",
message: "Error al procesar: " + errorThrown,
location: ["page"]
}]);
}
}
);
Recuerda: Si es una llamada al servidor desde JavaScript, ¡siempre APEX API! Es la garantía de tu checksum de sesión.
Redirecciones Seguras con APEX_UTIL.PREPARE_URL
Cuando necesites construir un enlace o redirección a otra página de APEX, es fundamental incluir los controles de seguridad necesarios.
Redirecciones Declarativas (la opción más segura): La forma más sencilla y segura de redireccionar es a través de la configuración declarativa en un Botón o un Proceso de Página (Branching):
Tipo de Redirección: Seleccionar
Redirect to Page in this Application.Página de Destino: Indicar el número de página (ej.,
#2).Configuración de Seguridad: En la sección Set Items, asignar los valores a los ítems de destino (
P2_DEPARTAMENTO,P2_ID_REGISTRO). APEX se encarga automáticamente de:Sanear los valores.
Generar y verificar el Checksum de Sesión para garantizar que la URL no haya sido alterada por el usuario.
Redirecciones en PL/SQL (Solo si es necesario): Si la redirección debe ser lógica o condicional, utiliza las funciones
APEX_UTIL.PREPARE_URLyAPEX_UTIL.REDIRECT_URL. La primera garantiza que se incluya el checksum (hash de seguridad) para evitar la manipulación de la URL por parte del usuario.
DECLARE
l_url VARCHAR2(4000);
BEGIN
-- Uso de APEX_UTIL.PREPARE_URL para construir la URL con checksum
l_url := APEX_UTIL.PREPARE_URL(
p_url => 'f?p=' || :APP_ID || ':2:' || :APP_SESSION, -- Redirecciona a la página 2
p_items => 'P2_DEPARTAMENTO,P2_ID_REGISTRO', -- Ítems de la página 2 que recibirán valores
p_values => 'VENTAS,' || :P1_ID_ACTUAL, -- Valores a pasar a los ítems
p_checksum_type => 'SESSION' -- Genera el checksum basado en la sesión (Seguro)
);
-- Redirección final
APEX_UTIL.REDIRECT_URL(p_url => l_url);
END;
Conclusión
La seguridad en Oracle APEX es una responsabilidad compartida: el framework se encarga de la arquitectura (sesiones, autenticación), pero el desarrollador es el guardián de la codificación (PL/SQL y JavaScript). Al priorizar las Variables de Enlace y el Saneamiento de la Salida, estarás blindando tus aplicaciones contra los ataques más comunes y demostrando un compromiso con la calidad profesional.
¡Pon a prueba tu código! ¿Cuál de estas vulnerabilidades has encontrado o solucionado en el pasado? Comparte tu experiencia o tu "regla de oro" de seguridad que no mencionamos aquí.
La seguridad evoluciona rápido. ¿Hay alguna nueva amenaza que los desarrolladores APEX debamos monitorear? Únete al debate en los comentarios.
¿Quieres más Insights APEX de este calibre? Suscríbete a nuestro blog para recibir notificaciones directas sobre rendimiento, desarrollo avanzado y, por supuesto, más seguridad.
No te pierdas la próxima entrega de APEX Insights, donde exploraremos como mejorar la experiencia del usuario en APEX. ¡Síguenos para no quedarte atrás!
Referencias
Para un estudio más profundo de estos temas, consulta las siguientes fuentes:
- Directrices de desarrollo seguro de Oracle APEX: La documentación oficial que detalla la configuración de seguridad y las APIs.
- Proyecto OWASP Top 10 (A03: Inyección y A07: XSS): El estándar de la industria para comprender la amenaza.
- API de JavaScript de APEX (
apex.server.process): Asegura que tus llamadas AJAX sean seguras con checksums.





