Since lesson 4.9.2, every request has its office, and the tenant filter of EF Core is at work. Whether the Kladde is tight now, nobody knows yet. “We filter by the office everywhere” is a claim, and a single forgotten filter is enough for one office to see the data of another. In this lesson you prove the isolation, and you do it the way an attacker would: One office attacks every place in the Kladde with what belongs to another office. You will find bugs. That is the purpose of the lesson.

What a leak between offices looks like

A leak is not only the foreign customer list on the screen. One office learns something about another as soon as any answer of the Kladde changes because the other office exists:

Kind Example How it comes about
a foreign record through its ID GET /api/contacts/{id} with the ID of a contact from office North returns it the query looks only for the ID
foreign rows in a list the trash shows deleted contacts of all offices a switched-off filter
changing foreign rows PUT on the ID of a foreign quote changes it loading without the office, then saving
a number “You have 214 contacts” although the office has 12 a count in SQL without a condition on the office
a difference in the error 403 for a foreign ID, 404 for one that does not exist the Kladde reveals that the foreign ID exists

The last row deserves one more sentence. If the Kladde answers a foreign ID with “forbidden” and an unknown one with “not found”, an office can try out which IDs exist. The rule is therefore: What belongs to another office does not exist. A foreign ID gets the same answer as one that was never issued.

In the security world, the first kind has a name of its own: Broken Object Level Authorization, at the top of the list of the most common weaknesses of APIs (OWASP API Security Top 10). Since 4.8.2 it has been in your threat model; now it gets its proof.