// Creates an Objection query.
// I have no control over the creation of the query. I can only modify the query after it has been created.
// Example: "select `todos`.* from `todos` where `text` = ?"
const objectionQuery = thirdPartyService.createQuery(userControlledInput);
// Adds an access check. Example "select `todos`.* from `todos` where `text` = ? and `userId` = ?"
objectionQuery.andWhere("userId", currentUser.id);
The above example has a security bug. If the thirdPartyService
generates a query like this:
select `todos`.* from `todos` where `text` = ? or `id` = ?
Then after adding the access check we will get the following query:
select `todos`.* from `todos` where `text` = ? or `id` = ? and `userId` = ?
And this query can return data that doesn't belong to the current user. To fix this bug, we need to enclose the user-controlled conditions in parentheses:
select `todos`.* from `todos` where (`text` = ? or `id` = ?) and `userId` = ?
But how do I do this with the Objection query builder? I imagine something like this:
const objectionQuery = thirdPartyService.createQuery(userControlledInput);
wrapWhereClauses(objectionQuery);
objectionQuery.andWhere("userId", currentUser.id);
One way could be to wrap the original query to be subquery / temporary table:
(please let me know if this works at all, I haven't tested it)