Inferencia de datos

Deja un comentario

Como sabes, las bases de datos son muy útiles para guardar y procesar datos pero también pueden conllevar un compromiso con la seguridad de los mismos. Muchas veces lo que se guarda en sus tablas es para que lo vean solamente algunos usuarios, no todos los usuarios.

Esto es más importante en las aplicaciones que se diseñan para los organismos de seguridad (militares, policías, servicios de inteligencia, etc.) pero también puede ocurrir con empresas comerciales.

¿Qué significa inferir?

Según el Diccionario es obtener una conclusión, deducir algo a partir de los datos con los que se cuenta.

Ejemplo

Tenemos una tabla llamada SALARIOS donde se guarda el salario de cada empleado de la Empresa. El personal de Recursos Humanos es el encargado de elaborar los cheques de pago a esos empleados, pero no deben conocer el salario de los empleados de nivel superior, solamente deben conocer el salario de los empleados de nivel medio y nivel bajo.

INFERIR1

Captura 1. Si haces clic en la imagen la verás más grande

En la Captura 1 estamos viendo el Identificador del Empleado, el Número del Mes, el Número del Año y el Monto de su salario. El Gerente de Recursos Humanos es “Juan” y él sí puede ver esa tabla. Pero su empleada “María” no debería ver el salario del empleado cuyo Identificador es 3, o sea que “María” debería ver esto:

INFERIR2

Captura 2. Si haces clic en la imagen la verás más grande

Al mirar esa tabla ella nota que está faltando un empleado con Identificador igual a 3, y entonces cuando la Empresa contrata a un nuevo empleado cuyo nombre es “Martín” ella trata de usar el Identificador 3 para asignárselo a “Martín” y así no tener números de Identificación faltantes. Pero como el Identificador 3 sí existe (aunque ella no puede verlo) al intentar grabar los datos de “Martín” obtendrá un mensaje de error. Y como “María” es inteligente entonces infiere (es decir: deduce) que sí existe un empleado con Identificador igual a 3 pero que a ella no le permiten verlo.

Y como además de inteligente es curiosa a partir de ese momento se dedica a intentar averiguar los datos del empleado con Identificador 3, mediante tablas cruzadas, o algunas otras técnicas.

Diseñando para evitar inferencias

Si algún usuario puede inferir (deducir) que algo se le está ocultando entonces puede también inferir (deducir) que se trata de algo valioso, algo de lo cual podrá obtener provecho económico o de otro tipo. Por algo se le ocultan los datos ¿verdad?.

Entonces, cuando diseñamos nuestras bases de datos debemos pensar en como evitar las inferencias. No es fácil ante usuarios inteligentes y con muchos conocimientos de Informática pero debemos intentarlo.

La primera y elemental medida es impedir que los usuarios puedan asignar identificadores o códigos. Estos deberían ser elegidos y puestos automáticamente por el Servidor del Firebird o por nuestra aplicación.

Lo segundo a recordar siempre es que los identificadores son para uso interno y los códigos son para uso externo. Eso implica que los usuarios jamás deberían ver los identificadores (ni siquiera necesitan saber que existen) y manejarse siempre exclusivamente con códigos. En general los códigos no deberían cambiarse pero si se cambian no afectarán a la operatividad de la Base de Datos porque ésta no los utiliza para nada, son solamente para mostrárselos a los usuarios.

Tercero, los códigos no deberían ser de la forma “A, B, C, D, E, …” o de la forma “1, 2, 3, 4, 5, …” porque si falta una letra o un número en la secuencia entonces es muy fácil inferir que algo se está ocultando.

Conclusión:

Cuando se diseña una Base de Datos un aspecto importante es el relacionado con la seguridad de los datos. Y dentro de la seguridad hay que tomar en cuenta que los usuarios no autorizados a ver una información no puedan realizar inferencias para saber que esa información existe.

En el caso de nuestro ejemplo “María” rápidamente descubrió que se le estaban ocultando los salarios del empleado cuyo Identificador es 3. ¿Por qué? porque la Base de Datos estaba mal diseñada y se le permitía a ella asignar un Identificador al nuevo empleado. En una Base de Datos bien diseñada ningún usuario, por ningún motivo, puede asignar o cambiar un Identificador o un Código. Si alguna vez se requiere hacer eso entonces debería hacerse exclusivamente usando nuestra aplicación.

Artículos relacionados

Usando IDENTIFICADORES y CÓDIGOS en nuestras tablas

El índice del blog Firebird21

Anuncios

Generando códigos dependientes

3 comentarios

A veces podemos encontrarnos con la siguiente situación: debemos codificar a los ítems pero esos códigos deben empezar con algunos caracteres predeterminados.

O sea, podríamos tener esta clase de códigos: AAC00001, AAC00002, AAC00003, CAM00001, CAM00002, ESC00001, ESC00002, ESC00003, etc.

Como ves, algunos códigos empiezan con AAC, algunos con CAM, algunos con ESC, etc. Y en cada caso la numeración empieza con 00001.

Una solución es la siguiente:

  1. Creamos una tabla de categorías, donde guardaremos las iniciales de los códigos (AAC, CAM, ESC, etc.). Esa columna debe tener la restricción Unique Key para que no tengamos códigos repetidos
  2. Creamos una tabla de bienes, donde se guardarán los códigos dependientes (AAC00001, AAC00002, AAC00003, etc.)
  3. A la columna donde guardaremos el código del bien le agregamos la restricción Unique Key
  4. En la tabla de bienes, creamos un trigger que se encargará de generar el código dependiente

CODIGO1

(haciendo clic en la imagen la verás más grande)

En la imagen de arriba podemos ver la estructura de la tabla CATEGORIAS. La columna CAT_INICIA debe tener la restricción Unique Key para asegurarnos que no tengamos iniciales repetidas.

CODIGO2

(haciendo clic en la imagen la verás más grande)

 En la imagen de arriba podemos ver algunas filas de la tabla CATEGORIAS.

CODIGO3

(haciendo clic en la imagen la verás más grande)

En la imagen de arriba podemos ver la estructura de la tabla BIENES. Recuerda que la columna BIE_CODIGO debe estar declararada como Unique Key para que el Firebird nos impida tener dos códigos idénticos.

A continuación, creamos un trigger como el siguiente:

SET TERM ^ ;

CREATE TRIGGER BIENES_BI FOR BIENES
   ACTIVE BEFORE INSERT
   POSITION 1
AS
   DECLARE VARIABLE lcCodigo D_CHAR8;
   DECLARE VARIABLE lnNumero D_CANTIDAD;
   DECLARE VARIABLE lcInicia D_CHAR3;
BEGIN

   /* Primero, se halla el último código de esta categoría */
   FOR SELECT
      BIE_CODIGO
   FROM
      BIENES
   WHERE
      BIE_IDECAT = NEW.BIE_IDECAT
   ORDER BY
      BIE_CODIGO
   INTO
      :lcCodigo
   DO BEGIN
   END

   /* Si no se encontró, el número será 1. Si se encontró, será el siguiente */
   IF (lcCodigo IS NULL) THEN
      lnNumero = 1;
   ELSE
      lnNumero = CAST(RIGHT(lcCodigo, 5) AS INTEGER) + 1;

   /* Se obtienen los caracteres iniciales del código */
   lcInicia = (SELECT CAT_INICIA FROM CATEGORIAS WHERE CAT_IDENTI = NEW.BIE_IDECAT);

   /* Se forma el código del bien que se grabará en la tabla */
   NEW.BIE_CODIGO = lcInicia || LPAD(lnNumero, 5, '0');

END^

SET TERM ; ^

Luego de insertar algunas filas en la tabla de BIENES esto es lo que obtenemos:

CODIGO4

(haciendo clic en la imagen la verás más grande)

Los usuarios solamente introdujeron el Identificador de la Categoría y el Nombre del Bien. El Identificador del Bien y el Código del Bien (la columna BIE_CODIGO) fueron puestos automáticamente por los triggers.

Observaciones:

  • En este ejemplo los códigos de los bienes empiezan con 3 caracteres predeterminados, pero pueden ser 2, 4, 5, ó cualquier otra cantidad. Eso se determina en la columna CAT_INICIA de la tabla CATEGORIAS
  • En este ejemplo los números tienen 5 dígitos y por lo tanto pueden variar entre 00001 y 99999 pero se pueden usar 2 dígitos, 3 dígitos, 7 dígitos o cualquier otra cantidad. Eso se determina en la columna BIE_CODIGO de la tabla BIENES. Como en este ejemplo la columna CAT_INICIA tiene 3 caracteres y el número máximo que se quiere usar es 99999 entonces la columna BIE_CODIGO tiene 8 caracteres.
  • Si más de una persona están introduciendo bienes al mismo tiempo entonces puede ocurrir que generen el mismo código del bien. Para evitar que se  graben códigos duplicados es que se debe usar la restricción Unique Key en la columna BIE_CODIGO. La primera persona grabará sin problemas, pero la segunda no podrá grabar porque el código ya existe y deberá volver a presionar el botón “Grabar” para que se genere un nuevo código del bien y allí sí se grabarán sus datos (bueno, si tiene mala suerte otra persona ya generó ese mismo código y deberá presionar el botón “Grabar” nuevamente hasta que tenga éxito. Si esta es una situación frecuente lo más conveniente es que sea el programa el encargado de reintentar la grabación hasta conseguirla).

Artículos relacionados:

https://firebird21.wordpress.com/2013/03/29/cast/

https://firebird21.wordpress.com/2013/04/10/lpad/

https://firebird21.wordpress.com/2013/04/14/right/

https://firebird21.wordpress.com/2013/03/17/entendiendo-a-los-triggers/