Medidas básicas de seguridad para aplicaciones Access – Dividir el proyecto

Divide y vencerás

La seguridad en entornos multiusuario para aplicaciones Access no viene configurada por defecto. Hasta la versión 2007 el propio Access traía integrado un sistema de permisos y de cifrado de los datos que se podía romper fácilmente. A partir de esa versión, Microsoft decidió eliminar  el sistema de permisos y cambiar el cifrado de datos unificando lo que antes era “Proteger la base de datos con contraseña” y “Cifrar la base de datos”.

Este paso mejora bastante la seguridad, ya que el cifrado se realiza directamente al proteger con contraseña la base de datos utilizando un algoritmo basado en la propia contraseña. No hay mucha información sobre el método de cifrado,  pero se supone que puedes elegir algoritmos de hasta 128 bits, lo que supone igualarse a plataformas en principio mucho más potentes (Edito: Después de buscar bastante, parece claro que Access 2007 utiliza RC4 de 40 bits modificable y Access 2010 utiliza AES de 128 bits por defecto).

En cuanto al sistema de permisos, deja al desarrollador vía libre para diseñar uno propio, que por muy malo que sea, difícilmente será peor que el que traía por defecto en versiones anteriores. Partiendo de la base de que cuanto más personal y poco standard sea un sistema de seguridad, más seguro será este, voy a intentar explicar unos pasos básicos para hacer las aplicaciones Access más seguras, dejando los sistemas de seguridad finales a los propios desarrolladores.

En esta serie de artículos sobre seguridad en Access trataré de ir desarrollando mediante ejemplos los pasos a seguir para hacer una aplicación Access conectada a una base de datos Access tanto o más segura que una aplicación orientada a entornos en principio más seguros. No hay duda de que si disponemos de medios para funcionar con Oracle, o incluso con Visual Basic contra SQL-Server, no tiene sentido no hacerlo, pero hay casos en los que esto no es posible y para esos casos (muy habituales tanto en PYMES como en aplicaciones departamentales de grandes empresas) están pensados estos artículos.

Voy a empezar con algo que aunque en principio parece sencillo y básico, hacerlo realmente seguro es algo más complicado. Dividir la base de datos en lo que llamaremos Front-End (FE) o aplicación y Back-End (BE) o datos.

Como todo usuario medio/alto de Access sabe, para entornos multiusuario hay que dividir el proyecto en un archivo para datos (que estará en el servidor) y la aplicación en si misma (que estará en cada equipo cliente). El procedimiento es sencillo, hay un apartado en “Herramientas de la base de datos” que realiza todo el proceso.

Dividir Base de datos

Imagen 1 – Dividir Base de datos

Una vez dividida la base de datos, tendremos 2 archivos, en nuestro caso Prueba_Seguridad (FE) y Prueba_Seguridad_be (BE). Con esto podríamos empezar a funcionar instalando el FE en cada uno de los equipos cliente pero nuestros datos estarían sin cifrar y sin proteger, se podría acceder directamente al BE.

Como he comentado al principio del artículo, a partir de Access 2007, podemos proteger el BE con contraseña a la vez que ciframos los datos simplemente abriendo la base de datos en modo exclusivo y utilizando la funcionalidad “Cifrar con contraseña” del menú archivo. Sobra decir que intentaremos utilizar contraseñas fuertes (letras mayúsculas, minúsculas, cifras, alfanuméricos…), ya que por muy fuerte que sea el sistema de seguridad, si lo protegemos con contraseñas débiles, nos puede traer problemas (aunque en artículos posteriores veremos que se pueden crear sistemas de control de acceso de varios niveles).

Cifrar base de datos

Imagen 2 – Cifrar base de datos

Una vez protegidos los datos con cifrado y contraseña, observamos que ahora no podemos abrir las tablas vinculadas desde nuestro FE. La solución que se tiende a utilizar es volver a vincular las tablas. Con esto, Access nos vuelve a pedir la contraseña y la guarda en la propiedad Connect del objeto TableDef, que un posible atacante podría utilizar para romper nuestra seguridad (esto puede parecer complicadísimo, pero simplemente cambiando la vista de Access para que muestre las tablas de sistema podremos ver la contraseña en la columna Connect de la tabla MSysObjects).

Para evitar esto, utilizaremos un método sencillo y eficaz para conectar nuestro FE con el BE sin necesidad de almacenar la contraseña de nuestra base de datos. Vincularemos las tablas antes de proteger el BE con contraseña (que en principio produciría un error al intentar manejarlas) pero al inicio de nuestra aplicación abriremos un recordset mediante código que permanecerá abierto durante la ejecución de la aplicación, dejando así abierta la conexión al BE, lo que nos permitirá no introducir la contraseña desde el FE.

Una posible implementación (no la más eficaz, pero eso lo dejo para cada desarrollador) podría ser la siguiente:

  • -Vincular las tablas antes de proteger el BE con contraseña.
  • -Proteger y cifrar el BE
  • -Crear una tabla sin datos en el BE (la llamaremos FALSA) y dejarla sin vincular.
  • -Abrirla por código al inicio de la aplicación cargando un formulario.
  • -Cargar en el recordset del formulario los datos.
  • -Ocultar el formulario e iniciar la aplicación.

El código que tendría el formulario al cargarse sería el siguiente:

Private Sub Form_Load()
Dim MiBD As DAO.Database
Dim rs_seguridad As DAO.Recordset

Set MiBD = CurrentDb
Set rs_seguridad = MiBD.OpenRecordset("SELECT * from FALSA IN '' [MS Access;PWD=Contraseña;DATABASE=RUTA SERVIDOR\Prueba_Seguridad_be]”, dbOpenDynaset)

Set Me.Recordset = rs_seguridad

End Sub

Donde Contraseña será la contraseña de nuestro BE (edito:Ahora que sabemos como encriptar contraseñas con Sha-2, podemos encontrar una solución mejor para no tener que escribir la contraseña en el código de nuestro proyecto. Una posible implementación sería pasar la contraseña ya encriptada a una función que la desencripte con un algoritmo simétrico aplicando varias capas, por ejemplo con hashes) y RUTA SERVIDOR será la ruta en la que tengamos nuestro BE.

Al ocultar el formulario y dejarlo abierto durante la ejecución de la aplicación, Access nos permite abrir las tablas vinculadas sin necesidad de introducir la contraseña y sin que quede guardada en ningún sitio. Hay otras muchas opciones para realizar esta operación, por ejemplo aprovechar el formulario de login, que más tarde explicaré, pero como decía antes, cuanto más personalizada sea la seguridad de la aplicación, más difícil de romper resultará.

En estos momentos ya disponemos de un proyecto mucho más seguro. El BE está cifrado y protegido con contraseña, podemos acceder desde nuestro FE a las tablas directamente y la contraseña no se guarda. Falta mucho, pero es un buen inicio.

The following two tabs change content below.
Llevo más de 10 años programando, sobre todo en Visual Basic y con bases de datos Access. Para mí, VBA y Access siguen siendo herramientas muy potentes. He desarrollado varios proyectos con PHP y MySql. Si sumo las webs que he tenido, probablemente pasaría de 100. Ahora prefiero dedicar todo mi esfuerzo a este blog (aunque sigo manteniendo unas cuantas...). Trabajo en la administración pública (si, soy funcionario), pero he trabajado en pequeñas empresas e incluso en una "grande" de las telecomunicaciones. Ultimamente estoy bastante metido en abrirme nuevos horizontes con C# y .NET. Renovarse o morir!

6 Respuestas a Medidas básicas de seguridad para aplicaciones Access – Dividir el proyecto

  1. Hola Arkaitz,

    muy bueno tu articulo! Realmente necesito unas soluciones de seguridad de bases de datos para mi puesto de trabajo y tu blog me esta resultando muy util.

    Eso si, tengo un pequeño problema a la hora de establecer la conexion con la tabla «falsa» para poder mantener la conexion con el back-end, y es que no acierto a escribir el formato correcto de sentencia SQL para la conexion con tabla externa, incluyendo la contraseña.

    La sentencia que utilizo es la siguiente:

    SELECT * FROM FALSCH IN ‘[MS Access;PWD=Password;DATABASE=C:\Datenbank_TV-300_Sicherheitsprobe_be;]’

    y siempre me arroja el runtime error 3125: el ultimo elemento de la sentencia (donde se especifica el origen de la tabla) es invalido. He probado distintas variaciones de ésta (quitando el «MS Access», quitando la extension «.accdb», quitando el punto y coma) y nada, sigue sin funcionar. Sabes dónde puede estar el fallo?

    Un cordial saludo, y gracias por tus aportes.

    Alejandro

  2. Prueba así:

    CurrentDb.OpenRecordset(«SELECT * FROM FALSCH IN » [MS Access;PWD=Password;DATABASE=C:\Datenbank_TV-300_Sicherheitsprobe_be.accdb]», dbOpenDynaset)

    Copia y pega por si acaso. Después de IN son 2 comillas simples y la SELECT va entre comillas dobles al abrir el recordset.

    Si ves que no te funciona, prueba cambiando el nombre del BackEnd por algo más sencillo, a veces parece que da errores…

    Un saludo

  3. Hola Arkaitz,

    perdon por no contestar antes. Estuve liado con otros proyectos y tuve que dejar un poco de lado el tema de la seguridad.

    He probado con lo que has puesto ahi y me arrojaba siempre el error 3125. Al final usé la siguiente sentencia y me funcionó:

    SQLString = «SELECT * FROM [C:\Datenbank_TV-300_Sicherheitsprobe_be.accdb;PWD=Password].FALSCH»

    Set rs_Sicherheit = CurrentDb.OpenRecordset(SQLString, dbOpenDynaset)

    Muchas gracias y un saludo!

  4. ikasten2 dice:

    Hola Arkaitz, buen artículo.

    Siguiendo lo dicho en el articulo llegamos a tener dos archivos access , si en adelante necesito hacer un cambio en el esquema de BD (ej: añadir nuevas tablas ala BD), ¿cómo lo puedo realizar?

    He intentado abrir directamente el archivo que contiene los datos y me sale un mensaje de error indicando «El archivo no contiene una firma digital y no se puede abrir. …».
    En cambio, si abro el archivo que contiene los formularios, todo va perfecto y puedo consultar las tablas (tanto sus datos como su esquema).

  5. Arkaitz Arteaga hace un tiempo utilice tu código para abrir el Back-End, pero ahora necesito modificar el código para que me permita especificar la ruta del Back-End que se encuentra guardada en un campo de una tabla del Front-End. (Espero haber sido claro)

    Set rs = CurrentDb.OpenRecordset(«SELECT Valores_Pre.* FROM Valores_Pre IN » [MS Access;PWD=Contraseña;DATABASE=C:\Proyecto\Base.accdb]», dbOpenDynaset)

    La idea es que «C:\Proyecto\Base.accdb» se pueda reemplazar por una variable que haga referencia a un campo de un formulario abierto

    Desde ya agradezco mucho tu tiempo

  6. Angel Egi dice:

    Hola Arkaitz, soy un fanático principiante de access, siguiendo tu curso he logrado hacer una pequeña aplicación front-end back-end, pero me surge un problema y no se como resolverlo, solo puedo conectar un usuario a la vez, cuando intento conectar otro usuario me da un error indicando: «Error al vincular tablas. No se puede cambia la contraseña de una base de datos compartida».
    Te agradecería alguna recomendación, gracias de antemano.

Deja una respuesta