Trying to understand Data API Builder (DAB) and if its right for my use case.
Based off a simple address book example, there is a table “Addresses” that would have columns:
-
User (the user of the address book, likely an ID linked from a User table)
-
Name
-
Email Address
In a standard web application (front end + back end) to get a list off all addresses belong to the app User, a back end function would take a User ID (de-crypted from the User authentication) and return all address linked to the User.
In the DAB example, the front end will be filtering/querying the address table based on the User ID same as above.
But what is to stop a hacker just incrementing User ID’s and extracting all address from the entire table or not even adding the the User ID to the query filter and getting the entire Address table?
The standard web app above has authorization to make sure only the User’s Addresses are returned.
Are my assumptions correct?
Are there solutions to fix this?
-
How do you make sure its only possible to return address linked to the the authorized User only?
-
Use a GUID for User ID and expose only a Stored Proc to DAB?
How do you make sure its only possible to return address linked to the the authorized User only?
The docs for DAB are pretty clear that you’d need to rely on its support for SESSION_CONTEXT
paired with row-level security in your underlying Azure SQL or SQL Server database engine to achieve this.
In a nutshell, you’d need to firstly enable said SESSION_CONTEXT
in your DAB configuration:
{
...
"data-source": {
"database-type": "mssql",
"options": {
"set-session-context": true
},
"connection-string": "<connection-string>"
},
...
}
Then, you’d create a function predicate in your database that performs a check based on the data in your tables and returns whether or not the data should be available to a particular user given the data that’s passed about them in said SESSION_CONTEXT
:
CREATE FUNCTION dbo.RevenuesPredicate(@username varchar(max))
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN SELECT 1 AS fn_securitypredicate_result
WHERE @username = CAST(SESSION_CONTEXT(N'name') AS varchar(max));
Lastly, you’d create the row-level security policy using the aforementioned predicate function, passing the data from the table to the predicate to allow it to make the determination if a particular row from the table should be shown to the current user described in the session data:
CREATE SECURITY POLICY dbo.RevenuesSecurityPolicy
ADD FILTER PREDICATE dbo.RevenuesPredicate(username)
ON dbo.Revenues;
Your ability to use this setup to meet a given requirement for data security is predicated on your authorization model being somewhat simple, your use of Azure SQL or SQL Server, and your direct reliance on the built-in authorization features of Static Web Apps. Anything of sufficient complexity beyond this will preclude the use of this feature.