Buenas Prácticas de Seguridad en Oracle APEX: Evita la Inyección SQL

Buenas Prácticas de Seguridad en Oracle APEX: Evita la Inyección SQL

La inyección SQL es una de las vulnerabilidades más comunes y peligrosas en aplicaciones web. En el caso de Oracle APEX (Application Express), aunque la plataforma ofrece protecciones integradas, también es posible que los desarrolladores introduzcan vulnerabilidades si no siguen las mejores prácticas.

En este artículo, exploraremos qué es la inyección SQL, cómo ocurre en Oracle APEX y, lo más importante, cómo prevenirla.

¿Qué es una inyección SQL?

La inyección SQL ocurre cuando un atacante manipula una entrada de usuario para alterar una consulta SQL. Esto puede permitirles acceder a datos confidenciales, modificar información o incluso tomar el control de la base de datos.

Ejemplo de un procedimiento con una consulta vulnerable:

BEGIN
IF APEX_COLLECTION.COLLECTION_EXISTS('cole_arti') THEN
        -- Eliminar la colección existente para evitar errores
        APEX_COLLECTION.DELETE_COLLECTION('cole_arti');
    END IF;
    APEX_COLLECTION.CREATE_COLLECTION_FROM_QUERY_B(
        p_collection_name => 'cole_arti',
        p_query           => 'SELECT CLAVE, NOMBRE, DESCR 
                               FROM articulo 
                               WHERE CLAVE ='|| :P17_ARTICULO
    );
END;

Si el valor de P17_ARTICULO no está validado, un atacante podría enviar algo como:

22 or 1=1

Esto transformaría la consulta en:

BEGIN
IF APEX_COLLECTION.COLLECTION_EXISTS('cole_arti') THEN
        -- Eliminar la colección existente para evitar errores
        APEX_COLLECTION.DELETE_COLLECTION('cole_arti');
    END IF;
    APEX_COLLECTION.CREATE_COLLECTION_FROM_QUERY_B(
        p_collection_name => 'cole_arti',
        p_query           => 'SELECT CLAVE, NOMBRE, DESCR 
                               FROM articulo 
                               WHERE CLAVE =22 or 1=1'
    );
END;

Esta instrucción devuelve todos los registros de la tabla.

¿Cómo puede ocurrir en Oracle APEX?

Aunque Oracle APEX incluye protecciones predeterminadas, como el uso de variables enlazadas en componentes generados automáticamente (reportes interactivos y formularios), los desarrolladores pueden introducir vulnerabilidades en situaciones como:

  1. Uso de consultas SQL o PL/SQL personalizadas:

    • Si concatenas cadenas directamente en una consulta SQL dinámica, puedes permitir la inyección SQL.

Ejemplo inseguro:

    EXECUTE IMMEDIATE 'SELECT * FROM articulo WHERE clave= ' || i_clave;
  1. Procesos PL/SQL personalizados:

    • Crear código que no valide o escape correctamente las entradas del usuario.
  2. Parámetros de URL no validados:

    • Si los parámetros en la URL se utilizan directamente en consultas SQL.

Buenas prácticas para prevenir la inyección SQL en Oracle APEX

A continuación, se presentan buenas prácticas que puedes implementar para evitar esta vulnerabilidad:

1. Usar variables enlazadas

Las variables enlazadas permiten que los valores del usuario sean tratados como datos, no como parte del código SQL.

Ejemplo seguro:

BEGIN
IF APEX_COLLECTION.COLLECTION_EXISTS('cole_arti') THEN
        -- Eliminar la colección existente para evitar errores
        APEX_COLLECTION.DELETE_COLLECTION('cole_arti');
    END IF;
    APEX_COLLECTION.CREATE_COLLECTION_FROM_QUERY_B(
        p_collection_name => 'cole_arti',
        p_query           => 'SELECT CLAVE, NOMBRE, DESCR 
                               FROM articulo 
                               WHERE CLAVE =:b1',
         p_names => apex_util.string_to_table('b1'),
         p_values => apex_util.string_to_table(:P17_ARTICULO)
    );
END;

En este caso, :P17_ARTICULO se trata como una variable y no como código ejecutable.

2. Validar las entradas del usuario

Asegúrate de que los valores proporcionados por los usuarios cumplan con las reglas esperadas (números, fechas, rangos, etc.). Oracle APEX proporciona validaciones integradas para los elementos de las páginas.

Ejemplo de validación:

  • Tipo de dato: Validar que un campo contenga solo números.

  • Longitud máxima: Restringir el tamaño de los campos.

3. Usar el paquete DBMS_ASSERT

El paquete DBMS_ASSERT ayuda a validar y sanitizar entradas antes de usarlas en consultas SQL.

Ejemplo:

l_value := DBMS_ASSERT.ENQUOTE_LITERAL(v_input);
EXECUTE IMMEDIATE 'SELECT * FROM articulo WHERE clave = ' || l_value;

4. Limitar los privilegios del esquema

Asegúrate de que las cuentas de base de datos utilizadas por Oracle APEX tengan solo los permisos mínimos necesarios. Esto reduce el impacto de un ataque exitoso.

5. Habilitar auditoría y registro

Registra intentos sospechosos de ingreso de datos y supervisa la actividad de la base de datos. Esto te ayudará a identificar posibles ataques.

6. Aprovechar las protecciones integradas de APEX

Oracle APEX utiliza variables enlazadas de forma predeterminada en formularios y reportes generados. Siempre que sea posible, utiliza estos componentes en lugar de crear consultas personalizadas.

Conclusión

Prevenir la inyección SQL en Oracle APEX es responsabilidad del desarrollador. Aunque APEX incluye muchas medidas de seguridad predeterminadas, es crucial seguir las mejores prácticas mencionadas para evitar vulnerabilidades.

Con un diseño cuidadoso, validaciones estrictas y el uso de variables enlazadas, puedes garantizar que tus aplicaciones APEX sean seguras y resistentes a ataques de inyección SQL.