17 de abril de 2007

Evitar la apertura de tablas contenidas en un DBC

Una gran falencia de VFP es el tema de la seguridad de los datos contenidos en su tablas nativas. Muchas veces queremos al menos evitar que con un simple USE los usuarios inexpertos curioseen nuestras tablas. Aquí un simple truco.

A partir de VFP7, podemos habilitar los eventos en los contenedores de bases de datos. Uno de los eventos que podemos controlar es el dbc_BeforeOpenTables, en el cual retornando un valor .F. nos impide abrir una tabla o vista contenida en un DBC.

En primer lugar debemos habilitar los eventos de nuestra base de datos, esto se logra mediante la función:
DBSETPROP("MiDBC", "DATABASE", "DBCEvents", .T.)
O también desde el menú Base de datos -> Propiedades, y marcando el cuadro de verificación "Activar eventos"

Una vez habilitados los eventos, debemos crear el procedimiento almacenado dbc_BeforeOpenTable y colocar el siguiente código:
PROCEDURE dbc_BeforeOpenTable(cTableName)
  LOCAL lcPass
  * En este ejemplo la "clave" la colocamos directamente
  * en el código, pero podemos tomarla de un archivo de texto,
  * una clave del registro de Windows, etc.
  lcPass = "PASSword"
  IF VARTYPE(gc_P_A_S_S) # "C" OR gc_P_A_S_S # lcPass
    PUBLIC gc_P_A_S_S 
    gc_P_A_S_S = INPUTBOX("Ingrese contraseña", "Aviso", "") 
  ENDIF 
  RETURN gc_P_A_S_S == lcPass 
ENDPROC
Este código interroga sobre el tipo y el valor de una variable pública; y si no coincide con nuestra clave nos presenta un cuadro de diálogo para ingresarla.

Ingresar contraseña

En caso que el valor ingresado con coincida, no se permitirá la apertura de la tabla.

Acceso denegado

Para evitar que se visualicen estos cuadros de diálogos en nuestras aplicaciones, debemos definir una variable Pública llamada gc_P_A_S_S y darle el valor de la clave elegida antes de intentar alguna tabla.

Debemos aclarar que esto no es una seguridad real para nuestros datos, ya que un usuario con pocos conocimientos podrá deshabilitar los eventos de nuestra base de datos con una simple línea de código como:
DBSETPROP("MiDBC", "DATABASE", "DBCEvents", .F.)
O simplemente averiguar la clave o modificar el procedimiento almacenado de la base de datos con:
MODIFY PROCEDURE

*** ACTUALIZACION ***
Como indica DragonNegro en su comentario, solo basta añadir el siguiente código en el evento OpenData para evitar el uso de los comandos MODIFY PROCEDURE ó DBSETPROP("MiDBC", "DATABASE", "DBCEvents", .F.).
PROCEDURE dbc_OpenData(cDatabaseName, lExclusive, lNoupdate, lValidate)
  *Immediately after DBC is opened.
  LOCAL lcPass
  lcPass = "PASSword" && Esta es la contraseña
  IF VARTYPE(gc_P_A_S_S) # "C" OR gc_P_A_S_S # lcPass
    PUBLIC gc_P_A_S_S
    gc_P_A_S_S = INPUTBOX("Ingrese contraseña para la base de datos: " ;
      + UPPER(JUSTFNAME(cDatabaseName)), "Aviso", "")
  ENDIF
  RETURN gc_P_A_S_S == lcPass
ENDPROC
*** FIN ACTUALIZACION ***

Aclaramos nuevamente que esto no es seguridad en nuestras tablas, sino una forma de complicar un poco su acceso. No podemos obtener una auténtica seguridad en nuestros datos sobre tablas nativas de Visual FoxPro, para ello debemos migrar los datos a otro motor de bases de datos como SQL Server o MySQL por ejemplo.

Hasta la próxima.

Luis María Guayán

1 comentario :

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.