---
title: "Firebase'i turvareeglite näited: 11 rünnatud reeglit"
description: "Firebase'i turvareeglite näited emulaatoris testituna: mida iga reegel külalisele või teisele kasutajale lubas, millised lekked jäid lahti ja mis need sulges."
url: "https://madsalt.tech/et/blog/firebase-security-rules-examples/"
author: "Denys Zaichenko"
author_url: "https://madsalt.tech/et/about/"
language: "et"
published: 2026-11-03
---

# Firebase'i turvareeglite näited: 11 rünnatud reeglit

Lühidalt

Saatsin samad päringud 11 Firestore'i reeglistikule külalisena, anonüümse kasutajana ja kolme sisseloginud kasutajana. `request.auth != null` lasi võõral lugeda, muuta ja kustutada kõigi tellimusi. Omaniku kontroll ainult `resource` peal lasi kasutajal anda tellimus kellelegi teisele. Üks lai `{document=**}` avas kollektsiooni, millel oli õige omanikureegel. Ja dokumenti salvestatud roll, mida kasutaja saab kirjutada, tegi ta ühe päringuga adminiks. Igaühel on all parandus ja parandatud reegel pidas samade päringute vastu.

Firebase'i rakenduse brauseri ja andmebaasi vahel pole teie serverit. Projekti konfiguratsioon on lehe sees ja [turvareeglid](https://firebase.google.com/docs/rules/insecure-rules) on see, mis seisab teie andmete ja kõigi vahel, kel see konfiguratsioon on. Seepärast tahtsin näiteid reeglitest koos rünnakuga, mitte nimekirja reeglitest, mis näevad õiged välja.

**Kuidas testisin.** Firebase Local Emulator Suite Firebase CLI 15.34.2-st, 3. novembril 2026. Laadisin iga reeglistiku, lähtestasin andmed ja kutsusin Firestore'i REST API-t päris tokenitega Auth-emulaatorist: ilma tokenita, anonüümne kasutaja, kasutajad A ja B ning võõras, kes oli ainult registreerunud. Andmed olid väljamõeldud: A-le kuuluvad tellimused `a1` ja `a2`, B-le `b1`.

## Millised Firebase'i reeglid lekivad?

| Reegel                                   | Päring                                    | Tulemus       |
| ---------------------------------------- | ----------------------------------------- | ------------- |
| `if true` (testrežiim)                   | Külaline loetleb tellimused               | `200`, kõik 3 |
| `if true` (testrežiim)                   | Külaline kustutab B tellimuse             | `200`         |
| `request.auth != null`                   | Anonüümne kasutaja loetleb tellimused     | `200`, kõik 3 |
| `request.auth != null`                   | Võõras kustutab A tellimuse               | `200`         |
| Omaniku kontroll ainult `resource` peal  | A loob tellimuse, mille omanik on B       | `200`         |
| Omaniku kontroll ainult `resource` peal  | A muudab oma tellimuse `ownerId`          | `200`         |
| Omanikureegel pluss `{document=**}` read | A loeb B tellimuse                        | `200`         |
| Kasutaja saab kirjutada oma `users` dok  | A paneb `role: admin` ja loeb B tellimuse | `200`         |

## Mida testrežiim tegelikult avab?

```
match /{document=**} {
  allow read, write: if true;
}
```

Kõik, kõigile. Ilma tokenita külaline loetles kõik 3 tellimust, kustutas ühe ja lõi uue. Selleks pole vaja kontot ega lekkinud saladust, ainult projekti id-d.

Kuupäevaga versioon, mida testrežiim tihti kasutab, ebaõnnestub teisiti. Kui on `if request.time < timestamp.date(2026, 1, 1)` ja see kuupäev on möödas, sai külaline `403` ja nii sai ka kasutaja A oma tellimust lugedes. Leke on läbi, aga ka rakendus.

## Kas `request.auth != null` piisab?

Ei. See ütleb ainult, et päringu taga on mingi konto.

```
match /orders/{id} {
  allow read, write: if request.auth != null;
}
```

Külaline sai `403`, mistõttu see reegel tundub kiires testis turvaline. Seejärel võõras, kes oli ainult registreerunud, loetles kõik 3 tellimust, muutis B tellimuse summat ja kustutas A tellimuse, kõik `200`-ga. Ka anonüümne kasutaja loetles kõik 3. Kui registreerumine on lahti, tähendab see reegel "kõik, kes vaevuvad registreeruma". Firebase'i dokumentatsioon loetleb selle samuti [tavaliste ebaturvaliste mustrite](https://firebase.google.com/docs/rules/insecure-rules) hulgas.

## Miks vajab omaniku kontroll nii `resource` kui ka `request.resource`?

`resource` on dokument sellisena, nagu see on salvestatud. `request.resource` on dokument sellisena, nagu see pärast kirjutamist oleks. Reegel, mis vaatab ainult esimest, kontrollib, kellele rida praegu kuulub, ja ei ütle midagi selle kohta, milleks kasutaja selle muudab.

```
match /orders/{id} {
  allow read, update, delete: if resource.data.ownerId == request.auth.uid;
  allow create: if request.auth != null;
}
```

Lugemised nägid õiged välja: A sai oma tellimusel `200` ja B tellimusel `403`. Kirjutamised mitte. A lõi uue tellimuse, mille `ownerId` oli B, ja sai `200`. Seejärel muutis A oma tellimuse `ownerId` B-ks, samuti `200`, ja B sai seda sestpeale lugeda. Rakenduses, kus tellimused on arved või saldod, on see kasutaja, kes kirjutab kellegi teise kontole.

See versioon keeldus kõigest:

```
match /orders/{id} {
  allow read, delete: if request.auth != null
    && resource.data.ownerId == request.auth.uid;
  allow create: if request.auth != null
    && request.resource.data.ownerId == request.auth.uid;
  allow update: if request.auth != null
    && resource.data.ownerId == request.auth.uid
    && request.resource.data.ownerId == resource.data.ownerId;
}
```

| A päring                        | Tulemus |
| ------------------------------- | ------- |
| Loe oma tellimus                | `200`   |
| Loe, uuenda, kustuta B tellimus | `403`   |
| Loo tellimus, mille omanik on B | `403`   |
| Muuda `ownerId` B-ks            | `403`   |

See lasi A-l siiski muuta oma tellimuse `total`, `200`-ga. Kui klient ei tohi seda välja määrata, öelge, milliseid välju ta tohib muuta:

```
allow update: if request.auth != null
  && resource.data.ownerId == request.auth.uid
  && request.resource.data.diff(resource.data).affectedKeys().hasOnly(['note']);
```

Sellega andis `total` muutmine `403` ja `note` muutmine `200`.

## Miks mu päring ebaõnnestus õige reegliga?

Sest [reeglid ei ole filtrid](https://firebase.google.com/docs/firestore/security/rules-query). Ülaltoodud omanikureegli puhul sai A, kes küsis kogu kollektsiooni, `403`, kuigi A omab 3 tellimusest 2. Firestore hindab päringut selle järgi, mida see võiks tagastada, mitte selle järgi, mis seal on.

| A päring               | Tulemus      |
| ---------------------- | ------------ |
| Loetle kõik tellimused | `403`        |
| Päring `ownerId == A`  | `200`, 2 dok |
| Päring `ownerId == B`  | `403`        |

Kui loend läheb reeglite karmistamise järel katki, parandage päringut. Reegli lõdvendamine, et loend toimiks, on viis, kuidas ülaltoodud laiad reeglid kirja saavad.

## Kas lai match võib tühistada õige reegli?

Jah, ja just seda otsiksin esimesena projektis, kus on pikk reeglifail. Firestore [lubab päringu, kui seda lubab mõni sobiv reegel](https://firebase.google.com/docs/firestore/security/rules-structure).

```
match /orders/{id} {
  allow read: if request.auth != null
    && resource.data.ownerId == request.auth.uid;
}
match /{document=**} {
  allow read: if request.auth != null;
}
```

Esimene plokk loeb nagu hea omanikureegel. Teise ploki olemasolul luges A B tellimuse `200`-ga, võõras loetles kõik 3 tellimust ja sama võõras luges A dokumendi kollektsioonis `users`. Esimeses plokis ei hoiata miski. Kustutage lai match; ühtegi võimalust, et hilisem reegel ligipääsu tagasi võtaks, pole.

## Kuidas kasutaja endast admini teeb?

See muster tuleb ette alati, kui rollid elavad dokumendis:

```
function isAdmin() {
  return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin';
}
match /users/{uid} {
  allow read, write: if request.auth.uid == uid;
}
match /orders/{id} {
  allow read: if resource.data.ownerId == request.auth.uid || isAdmin();
}
```

"Kasutajad saavad oma profiili muuta" ja "adminid saavad kõiki tellimusi lugeda" on kumbki eraldi mõistlikud. Koos on need õiguste eskalatsioon.

![Admin ühe päringuga. Kasutaja A, kelle oma users-dokument on kirjutatav. Enne: Kasutaja A → loe B tellimus → 403; Kirjuta oma roll: Kasutaja A → role: admin → 200; Pärast: Kasutaja A → loe B tellimus → 200.](https://madsalt.tech/charts/et/firebase-security-rules-examples.svg)

*Joonis 1. Minu test Firebase'i emulaatoris (CLI 15.34.2), 3. november 2026.*

Parandus on takistada kliendil seda välja kirjutada. Kui kirjutamisreeglisse lisada `request.resource.data.role == resource.data.role`, andis sama päring `403` ja A jäi B tellimusest välja. Serverist määratud custom claims on teine tee, sest klient ei saa neid muuta.

## Kaks asja, mis osutusid korda olevaks

Vanema reeglid ei lekki alamkollektsioonidesse. Kui `/orders/{id}` oli `allow read` igale sisseloginud kasutajale, luges A tellimuse, ja selle all olev `/orders/b1/notes/n1` andis `403`. See on [dokumenteeritud käitumine](https://firebase.google.com/docs/firestore/security/rules-structure): reeglid kehtivad ainult sobival teel.

Külaline ei lipsa läbi ka võrdlusest puuduva tokeniga. `resource.data.ownerId == request.auth.uid` andis külalisele `403` ka ilma eraldi `request.auth != null`-ita. Ma kirjutan kontrolli siiski välja, sest siis ütleb reegel seda, mida ta mõtleb.

## Kuidas oma reegleid kontrollida?

Käivitage oma päringud emulaatoris külalisena, võõrana ja teise kasutajana. See paljastas iga ülaltoodud juhtumi; reeglite lugemine mitte.

Esimeseks läbivaatuseks loeb tasuta [Firebase'i reeglite kontroll](https://madsalt.tech/et/tools/firebase-rules-checker/) kleebitud reegleid teie projekti puutumata. Siinsetel reeglistikel märkis see ära testrežiimi, ainult sisselogimist nõudva ligipääsu, laia matchi ja ise kirjutatud rolli. Ta loeb ainult teksti, seega ei oska ta öelda, millised teie andmed on ega kas reegel üldse avaldati.

Teie `apiKey` lehel ei ole iseenesest probleem. Firebase'i veebikonfiguratsioon on kavandatult avalik ja tasuta [secret scanner](https://madsalt.tech/et/tools/secret-scanner/) märgib seda nii, sest andmeid selle taga kaitsevad reeglid. Failidel on jälle teised reeglid ja leke, mida reeglid ei peata, mida testisin artiklis Firebase Storage'i reeglid.

**Piirangud.** Ainult Firestore, kohalikus emulaatoris, REST-i kaudu, väljamõeldud andmetel. Realtime Database kasutab teist reeglikeelt ja seda ei testitud. App Check, mis piirab, millised rakendused teie backendi kutsuda tohivad, ei kuulu siia; see ei asenda reegleid. Toodang võib emulaatorist erineda detailides, mida ma ei kontrollinud.

Pole kindel, mida teie reeglid läbi lasevad?

Loen need hea meelega koos teiega läbi. Müügijututa.

[Võtke ühendust](https://madsalt.tech/et/#contact)
