goldibex / targaryen

Test Firebase security rules without connecting to Firebase.
ISC License
242 stars 36 forks source link

Fix regression regarding invalid location given to RuleDataSnapshot methods #136

Closed dinoboff closed 6 years ago

dinoboff commented 6 years ago

Firebase does not allow operation with invalid location (fixed in #132) but it doesn't affect rule evaluation:

$> ./bin/targaryen-specs -a '{
  "users": {
    "rob": {
      "uid": "rob@example.com"
    }
  },
  "tests": [{
    "rule": "root.child(\"banned\" + auth.uid).val() != true",
    "user": "rob",
    "isValid": true,
    "failAtRuntime": false,
    "evaluateTo": true
  }]
}'

Result:

{
  "users": {
    "rob": {
      "uid": "rob@example.com"
    },
    "unauth": null
  },
  "tests": [
    {
      "rule": "root.child(\"banned\" + auth.uid).val() != true",
      "user": "rob",
      "isValid": true,
      "failAtRuntime": false,
      "evaluateTo": true
    }
  ]
}
{ Error: Targaryen and Firebase evaluation of "root.child("banned" + auth.uid).val() != true" diverges.
The rule have no runtime error.
    at MatchError (/targaryen/lib/parser/specs.js:28:5)
    at RuleSpec.compare (/targaryen/lib/parser/specs.js:284:13)
    at fixtures.tests.filter.forEach.t (/targaryen/bin/targaryen-specs:103:21)
    at Array.forEach (native)
    at test (/targaryen/bin/targaryen-specs:103:6)
    at process._tickCallback (internal/process/next_tick.js:109:7)
  spec:
   RuleSpec {
     rule: 'root.child("banned" + auth.uid).val() != true',
     user: 'rob',
     wildchildren: undefined,
     data: undefined,
     isValid: true,
     failAtRuntime: false,
     evaluateTo: true },
  targaryen: { isValid: true, failAtRuntime: true, evaluateTo: undefined } }
dinoboff commented 6 years ago

Same with RuleDataSnapshot#hasChild:

{
  "users": {
    "rob": {
      "uid": "rob@example.com"
    },
    "unauth": null
  },
  "tests": [
    {
      "rule": "root.hasChild(\"banned/\" + auth.uid) == false",
      "user": "rob",
      "isValid": true,
      "failAtRuntime": false,
      "evaluateTo": true
    }
  ]
}
{ Error: Targaryen and Firebase evaluation of "root.hasChild("banned/" + auth.uid) == false" diverges.
The rule have no runtime error.
    at MatchError (/targaryen/lib/parser/specs.js:28:5)
    at RuleSpec.compare (/targaryen/lib/parser/specs.js:284:13)
    at fixtures.tests.filter.forEach.t (/targaryen/bin/targaryen-specs:103:21)
    at Array.forEach (native)
    at test (/targaryen/bin/targaryen-specs:103:6)
    at process._tickCallback (internal/process/next_tick.js:109:7)
  spec:
   RuleSpec {
     rule: 'root.hasChild("banned/" + auth.uid) == false',
     user: 'rob',
     wildchildren: undefined,
     data: undefined,
     isValid: true,
     failAtRuntime: false,
     evaluateTo: true },
  targaryen: { isValid: true, failAtRuntime: true, evaluateTo: undefined } }
dinoboff commented 6 years ago

Or RuleDataSnapshot#hasChildren:


{
  "users": {
    "rob": {
      "uid": "rob@example.com"
    },
    "unauth": null
  },
  "tests": [
    {
      "rule": "root.hasChildren([\"banned/\" + auth.uid]) == false",
      "user": "rob",
      "isValid": true,
      "failAtRuntime": false,
      "evaluateTo": true
    }
  ]
}
{ Error: Targaryen and Firebase evaluation of "root.hasChildren(["banned/" + auth.uid]) == false" diverges.
The rule have no runtime error.
    at MatchError (/targaryen/lib/parser/specs.js:28:5)
    at RuleSpec.compare (/targaryen/lib/parser/specs.js:284:13)
    at fixtures.tests.filter.forEach.t (/targaryen/bin/targaryen-specs:103:21)
    at Array.forEach (native)
    at test (/targaryen/bin/targaryen-specs:103:6)
    at process._tickCallback (internal/process/next_tick.js:109:7)
  spec:
   RuleSpec {
     rule: 'root.hasChildren(["banned/" + auth.uid]) == false',
     user: 'rob',
     wildchildren: undefined,
     data: undefined,
     isValid: true,
     failAtRuntime: false,
     evaluateTo: true },
  targaryen: { isValid: true, failAtRuntime: true, evaluateTo: undefined } }```