Comment by ris
5 years ago
Amongst all the praise we're seeing for this approach here, may we please just have a minute's silence for the various exploits sqlite has seen when loading arbitrary database files over the years?
My recent favourite being https://media.ccc.de/v/36c3-10701-select_code_execution_from...
This concern was just raised on the SQLite Forum (probably after showing up here). See my reply at https://sqlite.org/forum/forumpost/8beceed68e for additional insights into the problem and recent SQLite enhancements to address it.
Absolutely, there are many things that can be done to mitigate this kind of thing, I'm merely advising caution over people immediately reaching for a solution where they're executing thousands upon thousands of lines of code over untrusted files when they can get away with something much simpler.
Interesting. That one only affects systems which add their own application-specific SQLite functions to the database after loading it.
That's probably a niche case which doesn't affect most systems. But it'd be good to know about and watch out for in the systems that do.
Is there any way to mitigate code execution issues (besides just fixing bugs)? Because allow code execution might be a pretty big deal breaker in certain contexts.
This is a security flaw of the system or application using SQLite, though. It is trusting data it should not trust and executing code provided with that data.
If I use libpng or libjpeg to decode an image and that causes a buffer overrun or another security vulnerability, that is very much a bug in libpng or libjpeg.
The same is true when I open a database in SQLite: if that causes a security problem, it's a bug in that library. I don't even see how you could validate a database file before you hand it over to SQLite.
The exploit mentioned above relies on third party functions being loaded into the database. eg application specific functions
Those functions have to be explicitly loaded by the application after loading the database. eg: They're not stored in the database and loaded with it.
You'd validate the database (past the standard integrity checking), by loading it and not adding any third party functions. Then check it's not doing anything dodgy with views, or outright disable views. Then load the third-party extensions (if needed).
If you wanted to go even further, you could also add an authorizer callback function:
https://www.sqlite.org/c3ref/set_authorizer.html
That's called (multiple times) any time a SQL statement is prepared/executed, and catches things like functions being run, tables being accessed, etc. You can use that to only allow a whitelisted set of functions to run, which would help in some scenarios. eg:
https://github.com/sqlitebrowser/dbhub.io/blob/e1c5042f857e9...
The "Defense Against Dark Arts" page on the SQLite website has further good info about this:
https://www.sqlite.org/security.html
As a data point, I implemented the above "Defense against Dark Arts" stuff recently for an online SQLite data publishing platform to let people run free form queries on databases (dbhub.io). It wasn't all that hard to implement. Much less so that I'd been expecting. :)
RTFM
https://www.sqlite.org/security.html
Huh? If you're using SQLite as an application file format, isn't opening untrusted files a key use case? What else, never share files with people? That must be a pretty boring application.
Sure but just like a web browser, it’s the application’s responsibility to sandbox or verify the code, not the http library’s.
3 replies →