Question

Does RedQueryBuilder api, which allows access to the tree of the query, not to the finished sql? I want to write secure way to receive SQL requests from the client, forming the final SQL on server. For example, the client may send:

{
    op: "AND",
    left: {
        op: "=",
        left: "name",
        right: "Bob"
    },
    right: {
        op: "<",
        left: "time",
        right: "1300000000" // now() timestamp
    }
} 
Was it helpful?

Solution 2

I'm afraid it doesn't.

In your example if "now()" is a a SQL fragment you would still have security issues?

I'd suggest that you see what options your database gives you to totally not trust the SQL. E.g. very low power user and only select against views

or you re-parse the SQL to check its contents (this seems like a poor man's version of using your databases to constrain the SQL).

Maybe add SQL as a tag? Might be a bit of religious war about allowing untrusted SQL to hit your database.

A further worry is to protect against DOS so the database may also be best placed to do resource limitation. e.g. client sends (in any format) a hideous Cartesian join.

OTHER TIPS

Finally, I use the SQL parser on the client side to construct conditions tree and send to server like json.

Its my simplified administration interface: https://gist.github.com/Somewater/5705567

in a nutshell: 
1) ReQueryBulder generate SQL request (string)
2) SQL Parser create SQL request structure
3) My code convert SQL Parser structure to simple json (as stated above)
4) send json to the server

And server request parser (ruby): https://gist.github.com/Somewater/5705620

And I can handle request on server like this (Rails request controller in my example):

include ConditionsBuilder
cond = JSON.parse(request.params['cond']) # conditions like json string
condTree = self.parse_sql_conditions_from_json(cond) # conditions like btree structure

# perform some conditions checks, for example, add additional conditions
permission_conds = And[ GtEq['permissions', 12], Eq['is_admin', 1] ]
condTree = And[condTree, permission_conds]


conditions = self.build_sql_conditions((Time.new - 90.days).to_i, Time.new.to_i, condTree)
# handle sql request: "SELECT * FROM tablename WHERE " + conditions.to_s
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top