Where we are right now

User writes this
SELECT * FROM profile WHERE email='{{context.arguments.email}}'
{
arguments: {
email: "john@example.com"
}
}
Template
Context
SELECT * FROM profile WHERE email='john@example.com'
Database
Result
SELECT * FROM profile WHERE email='{{context.arguments.email}}'
{
arguments: {
email: "john@example.com"
}
}
Template
Context
SELECT * FROM profile WHERE email='john@example.com'
Database
Result
Not easy to write
Insecure
a; DROP TABLE profile
Hard to check if query was correct or if there were errors
Can only write one statement
How can we make it better ?
Potential Options
- Keep the current approach but mitigate injection issues.
- Allow users to write some declarative meta language
- Allow users to write a small amount of custom code
Option 1 and 3 both involve using a library called Knex
1. Fix injection problems with Current Approach
SELECT * FROM profile WHERE email=?
[$context.arguments.email]
Query
Args
SELECT * FROM profile WHERE email='john@example.com'
Database
Result
Context
Approach 1 (continued)
- User defines the raw query + arguments to be passed
- Knex builds a safe SQL statement
Drawbacks
- SQL is hard to write
- User can still only write one statement per resolver
2. Allow users to write some declarative meta language
{
"profile": {
"where": {
"email": "$context.arguments.email"
}
}
}
Context
SELECT * FROM profile WHERE email='john@example.com'
???
- No existing solution we can leverage
- Building one would be really hard and is not in our interest
Approach 3 - Allow Users to Write Code

Approach 3 (Continued)
return db.select().from('meme').orderBy('id', 'desc')
JavaScript
{
db: Knex,
resolve: {
args: { ... },
// more graphql stuff
}
}
Sandbox
VM
Result
Approach 3
- User writes some javascript code with help of Knex.
- User code is run inside a sandboxed environment
- Cannot require()
- Cannot process.exit()
- etc.
- User can do multiple queries and write some small pieces of business logic.


Multiple Queries
Custom Business Logic
Drawbacks
- It's 5x slower than the original
- It can be modified so it's only a small bit slower.
- This opens up one case where the user code can crash the server
-
while(true) {}
Impact
- We can only do this if we agree that a user 100% owns their server
- If they cause problems, they have to deal with it.
- We will not be able to support running code from different users in the same server - It's too dangerous
- If we want to do multi tenancy, we will need to solve it at another level
Summary
Three approaches:
- Keep existing approach but mitigate injection issues with knex
- Can't do multiple queries
- Do people want to write SQL?
- Meta Language approach
- Might be nice but too much effort
- Users write some sandboxed code
- Flexible, multiple queries, business logic
- Multi-Tenancy Concerns
- Do people want to write JavaScript? :)
AeroGear DataSync Custom Resolvers Spike
By Dara Hayes
AeroGear DataSync Custom Resolvers Spike
- 1,078