Skip to content

Fail-open nested _where filtering #1731

@x4cc3

Description

@x4cc3

Bug: nested _where object filters fail open when the intermediate field is missing

Description

Nested _where object filters currently appear to fail open when the intermediate field does not exist on the target object.

In practice, a control filter that correctly returns an empty result can be turned into a broad match by wrapping the same condition inside an extra nested object. That makes the behavior surprising and inconsistent with the idea of restrictive filtering.

I do not think this is the same as the older generic filter issues such as #302; this looks more specific to nested _where evaluation.

Affected area

  • src/app.ts
  • src/matches-where.ts
  • src/parse-where.ts

Reproduction

Run this from the repository root:

node --input-type=module -e "import { createApp } from './src/app.ts'; import { Low, Memory } from 'lowdb'; const db=new Low(new Memory(), {}); db.data={posts:[{id:'1',title:'a'},{id:'2',title:'b'}]}; const app=createApp(db); const server=app.listen(4580, async ()=>{ const strict=encodeURIComponent(JSON.stringify({title:{eq:'zzz'}})); const bypass=encodeURIComponent(JSON.stringify({title:{nested:{eq:'zzz'}}})); const r1=await fetch('http://127.0.0.1:4580/posts?_where='+strict); const r2=await fetch('http://127.0.0.1:4580/posts?_where='+bypass); console.log('strict', await r1.text()); console.log('bypass', await r2.text()); server.close(); });"

Expected behavior

Both filters should return an empty result:

strict []
bypass []

Actual behavior

The nested version returns all rows:

strict []
bypass [
  {
    "id": "1",
    "title": "a"
  },
  {
    "id": "2",
    "title": "b"
  }
]

Why this happens

In matchesWhere(), nested object comparisons recurse only when the current field exists and is an object. If the field is missing, the code falls through with continue instead of returning false.

That turns a missing nested field into an implicit match.

Impact

This is at least a filtering correctness bug.

It may also matter for wrapper applications that rely on _where to narrow visible data, because a nested predicate that should exclude rows instead returns them.

Suggested fix

  • Treat missing or non-object intermediate fields as a mismatch for nested object predicates.
  • Add a regression test for nested missing-field cases.
  • Add a second regression test for the same behavior inside or conditions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions