Skip to content
Writing

Picking fields is not access control

If the only reason a client never sees a number is that the app forgot to ask for it, that is not a boundary. That is a habit.

access controlmulti-tenant

Two companies use the same app. Neither may see the other data, and neither may see certain numbers that belong to us. Normal multi-tenant work.

I went looking for where that was actually enforced, expecting to confirm it and move on. What I found was that the app was doing all of it. Every read asked the backend for a named list of safe fields, and because the app always asked politely, nothing sensitive ever came back.

That works right up until something asks differently.

The difference between a habit and a boundary

The backend was willing to return everything. It just was not being asked to. So the protection was:

  • every existing query remembering to name safe fields
  • every future query remembering the same
  • nobody ever calling the backend directly

The first two rely on discipline forever. The third is not something you can rely on at all, because a token that can read a collection can read all of it, from anywhere, whether or not your app is involved.

None of that is a boundary. A boundary is a thing that says no. This said nothing, and no one had noticed because the app had never asked an impolite question.

Order matters

The tempting fix is to tighten the app. More field lists, a helper that enforces them, a code review rule. That feels like progress and it changes nothing: the backend still hands over everything to anyone who asks.

So the order I planned was:

  1. Restrict it at the source. The permission itself should not expose the sensitive fields, so an impolite question gets nothing back. Now there is a real no.
  2. Keep the app filtering. Not as protection, but as a second layer, and to keep responses small.
  3. Stop computing sensitive things client side. If a number is worked out in the browser, its inputs were in the browser. The output being hidden does not matter.

Only step one is security. Steps two and three are what you add once the boundary exists.

What I keep from it

When you are told something is protected, ask what would happen if the app were removed from the picture. If the answer is “then everything comes back”, the app was never protecting it. It was just being well behaved.

Also worth saying: I found this by reading the permissions rather than the code. The code told me what we ask for. Only the permissions told me what we are allowed to have.

Get in touch

I am not looking for a full-time role, but I do take on projects. If you have something you want built, or something that is broken, send me an email with what you are trying to do.