Corregir reglas no seguras

Consulta esta guía para conocer las vulnerabilidades habituales en las configuraciones de las reglas de seguridad de Firestore, revisar y proteger mejor tus reglas, y probar los cambios antes de implementarlos.

Si recibes una alerta que indica que tu base de datos de Firestore en modo nativo no está protegida correctamente, puedes resolver las vulnerabilidades modificando y probando tus reglas de seguridad de Firestore.

Para ver las reglas de seguridad que ya tienes, ve a la pestaña Reglas de la consola de Firebase.

Información sobre las reglas de seguridad de Firestore

Las reglas de seguridad de Firestore protegen tus datos de usuarios malintencionados. Las reglas predeterminadas de cualquier instancia de Firestore en modo nativo creada en la consola de Firebase deniegan el acceso a todos los usuarios. Para desarrollar tu aplicación y acceder a tu base de datos, tendrás que modificar esas reglas y puede que te interese conceder acceso general a todos los usuarios en un entorno de desarrollo. Sin embargo, antes de implementar tu aplicación en un entorno de producción, dedica tiempo a configurar correctamente tus reglas y proteger tus datos.

Mientras desarrollas tu aplicación y pruebas diferentes configuraciones para tus reglas, usa el emulador de Firestore en modo nativo para ejecutar tu aplicación en un entorno de desarrollo local.

Situaciones habituales con reglas no seguras

Las reglas de seguridad de Firestore que hayas configurado de forma predeterminada o al desarrollar tu aplicación con Firestore en modo nativo deben revisarse y actualizarse antes de implementar la aplicación. Asegúrate de proteger correctamente los datos de tus usuarios evitando los siguientes errores comunes.

Acceso abierto

Al configurar Firestore en modo nativo, es posible que hayas definido las reglas para permitir el acceso abierto durante el desarrollo. Puede que pienses que eres la única persona que usa tu aplicación, pero si la has implementado, está disponible en Internet. Si no autenticas a los usuarios ni configuras reglas de seguridad, cualquier persona que adivine tu ID de proyecto podrá robar, modificar o eliminar los datos.

No recomendado: acceso de lectura y escritura a todos los usuarios.
// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this rule set in production; it allows
// anyone to overwrite your entire database.

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}
Solución: reglas que restringen el acceso de lectura y escritura.

Crea reglas que se adapten a tu jerarquía de datos. Una de las soluciones habituales para esta falta de seguridad es la seguridad basada en usuarios con Firebase Authentication. Consulta más información sobre cómo autenticar usuarios con reglas.

Solo el propietario del contenido

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated content owners access
    match /some_collection/{document} {
      // Allow reads and deletion if the current user owns the existing document
      allow read, delete: if request.auth.uid == resource.data.author_uid;
      // Allow creation if the current user owns the new document
      allow create: if request.auth.uid == request.resource.data.author_uid;
      // Allow updates by the owner, and prevent change of ownership
      allow update: if request.auth.uid == request.resource.data.author_uid
                    && request.auth.uid == resource.data.author_uid;

    }
  }
}
  

Acceso público y privado mixto

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      // Allow public reads
      allow read: if true
      // Allow creation if the current user owns the new document
      allow create: if request.auth.uid == request.resource.data.author_uid;
      // Allow updates by the owner, and prevent change of ownership
      allow update: if request.auth.uid == request.resource.data.author_uid
                    && request.auth.uid == resource.data.author_uid;
      // Allow deletion if the current user owns the existing document
      allow delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}
  

Acceso para cualquier usuario autenticado

A veces, las reglas de seguridad de Firestore comprueban que un usuario ha iniciado sesión, pero no restringen más el acceso en función de esa autenticación. Si una de tus reglas incluye auth != null, confirma que quieres que cualquier usuario que haya iniciado sesión tenga acceso a los datos.

No recomendado: cualquier usuario que haya iniciado sesión tiene acceso de lectura y escritura a toda tu base de datos.
service cloud.firestore {
  match /databases/{database}/documents {
    match /some_collection/{document} {
      allow read, write: if request.auth != null;
    }
  }
}
Solución: limita el acceso mediante condiciones de seguridad.

Cuando compruebe la autenticación, también puede usar una de las propiedades de autenticación para restringir aún más el acceso a usuarios específicos de conjuntos de datos concretos. Consulta más información sobre cómo añadir condiciones de seguridad y sobre el acceso basado en roles.

Acceso basado en roles

service cloud.firestore {
  match /databases/{database}/documents {
    // Assign roles to all users and refine access based on user roles
    match /some_collection/{document} {
     allow read: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
     allow write: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"

     // Note: Checking for roles in your database using `get` (as in the code
     // above) or `exists` carry standard charges for read operations.
    }
  }
}

Acceso basado en atributos

// Give each user in your database a particular attribute
// and set it to true/false
// Then, use that attribute to grant access to subsets of data
// For example, an "admin" attribute set
// to "true" grants write access to data

service cloud.firestore {
  match /databases/{database}/documents {
    match /collection/{document} {
      allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
      allow read: true;
    }
  }
}
  

Acceso público y privado mixto

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      allow read: if true
      allow write: if request.auth.uid == request.resource.data.author_uid
    }
  }
}
  

Acceso para direcciones de correo sin verificar

A veces, las reglas de seguridad de Firestore comprueban que el correo de un usuario pertenece a un dominio concreto. Aunque suele ser una buena práctica, los correos no siempre se verifican durante el inicio de sesión hasta que el usuario realiza un paso adicional al recibir un correo de verificación. Asegúrate de validar que el correo pertenece al usuario.

No recomendado: cualquier usuario puede iniciar sesión con una dirección de correo arbitraria.
service cloud.firestore {
  match /databases/{database}/documents {
    // Allow access based on email domain
    match /some_collection/{document} {
     allow read: if request.auth != null
                 && request.auth.email.endsWith('@example.com')
    }
  }
}
Solución: Limite el acceso solo a los correos verificados.

Verificar correos

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow access based on email domain
    match /some_collection/{document} {
     allow read: if request.auth != null
                 && request.auth.email_verified
                 && request.auth.email.endsWith('@example.com')
    }
  }
}

Acceso cerrado

Mientras desarrollas tu aplicación, otra práctica habitual es mantener tus datos protegidos. Normalmente, esto significa que has cerrado el acceso de lectura y escritura a todos los usuarios, de la siguiente manera:

// Deny read/write access to all users under any conditions
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Los SDKs de administrador de Firebase y Cloud Functions seguirán teniendo acceso a tu base de datos. Usa estas reglas cuando quieras usar Firestore en modo nativo como backend solo para el servidor junto con el SDK de administrador de Firebase. Aunque es seguro, debes comprobar que los clientes de tu aplicación puedan recuperar datos correctamente.

Consulta más información sobre las reglas de seguridad de Firestore y cómo funcionan en el artículo Empezar a usar las reglas de seguridad de Firestore.

Comprobar las reglas de seguridad de Firestore

Para comprobar el comportamiento de tu aplicación y verificar las configuraciones de tus reglas de seguridad de Firestore, usa el emulador de Firestore en modo nativo. Usa el emulador de Firestore en modo nativo para ejecutar y automatizar pruebas unitarias en un entorno local antes de desplegar cualquier cambio.

Para probar rápidamente las reglas de seguridad de Firestore actualizadas en la consola de Firebase, usa la herramienta Entorno de pruebas de reglas.

  1. Para abrir la zona de pruebas de reglas, haga clic en Zona de pruebas de reglas en la pestaña Reglas.
  2. En los ajustes de Entorno de pruebas de reglas, selecciona las opciones de la prueba, como las siguientes:
    • Pruebas de lectura o escritura
    • Una ubicación específica de tu base de datos, como una ruta
    • Tipo de autenticación: sin autenticar, usuario anónimo autenticado o ID de usuario específico.
    • Datos específicos de un documento a los que hacen referencia tus reglas (por ejemplo, si tus reglas requieren la presencia de un campo específico antes de permitir una escritura)
  3. Haga clic en Ejecutar y busque los resultados en el banner situado encima de la ventana de reglas.