Hacker News new | ask | show | jobs
by dvdkon 1881 days ago
My model attacker is a limited user that has access to an advanced search function with filtering on number inequality and/or string patterns akin to LIKE. Such an attacker could send a search query such as "id = 4829 AND cost > 1000" and measure the time that query took (over multiple executions). From the time data the attacker could then determine if object 4829 has a cost value of over 1000, gaining 1 bit of data. Through a binary search they could obtain the full value in logarithmic time.

If the authorization check was fast enough (which it probably is for performance reasons anyway), this would be reduced to the attacker obtaining statistical information (roughly how many objects have cost over 1000). That might be acceptable, my problem is that a benign-looking performane problem could become a serious security problem.

2 comments

Zanzibar doesn't actually contain any object data, only authorization metadata. So you can't do the complex queries you're suggesting against Zanzibar itself, and presumably the databases that store actual data have authz as a requirement prior to the actual query (which is fine bc Zanzibar is fast)
Could you elaborate on "prior to the actual query"? Do you mean taking some rough queryable subset and then calling Zanzibar for each object in that subset? That's how I'm handling it right now, I just hoped others had a more scalable solution.
No I mean that a user either has access to the database or not. If they do, you check access prior to the query. I think you're doing something related to row level permissions within a database.

And ultimately "Implementing side-channel secure row level security in a database" is a completely independent problem from "abstract authz checker, which is what zanzibar is. You might build a row level security infra atop zanzibar, but you'd probably do that within your database engine, with zanzibar serving as some sort of authz primitive.

From what I can see, Zanzibar is also intended for "row-level" access checks.

I also don't think it's such a separate problem. If you've got a set of authorization primitives, you should have some simple and foolproof way of applying them to various usecases. You might have the best policy description language and very fast evaluation, but what good is it as a central authz service when you can't securely implement search on top of it?

> From what I can see, Zanzibar is also intended for "row-level" access checks.

Yes, as a primitive for storing acl relations, not as a magic solves all security problems tool.

I thought about this more, and I think your usecase is simply unsolvable. You're allowing an untrusted user to take speculative action on something they may not have access to.

This is the same problem as spectre (and similarly unfixable). You'd need to do the acl-checks per row prior to the checks on the internal data. That is, as part of the operation `WHERE id = 123`, you need the database engine to check that you have access to the row, and only if they are acl'd, allow the check against X > 100. Otherwise, just pretend that id=123 isn't in the database.

Of course, this is a simple case, I expect that more complicated cases may not be solvable at all. Like I think the correct way is to say that certain (and perhaps all except the primary key) columns need authorization prior to access.

This is, I think, entirely a database implementation question, and ultimately has nothing to do with Zanzibar itself.

So to answer your question

> what good is it as a central authz service when you can't securely implement search on top of it?

You can, you just can't do it in the way you've described. Its a difficult problem that the central authz service shouldn't solve, and the design of this service is still faster than all of the others.

If your object IDs are 1, 2, 3... then attacker can check all the IDs. If instead each object ID is a 256-bit UUID, then the attacker can't make a query for every possible object ID.