views:

38

answers:

4

I want to give my website users arbitrary read-only access to an SQLite3 database, without letting them write to the database or do any other damage. How?

Making the db file read-only helps a little, but commands like "ATTACH", ".load" and ".output" allow people to read/write other files, which may not be protected.

Of course, if I knew all such commands, I'd just filter against them, but I'm mostly worried about commands I haven't thought of.

I tried briefly to alter sqlite3's source code to disallow writes, but this is harder than it looks: even the SELECT statement appears to do some internal INSERTS/etc.

Note: I've considered DOS attacks, and will ulimit cputime to 5s or something. My main concern is damage to files/"hacking", not DOS.

chroot() may work, but seems extreme.

Thoughts?

A: 

Try making the sqlite database file read only.

If you need to update it:

1)block read access from users.

2)give it a write bit.

3)make your modifications.

4)then remove the write bit. 

5)Restore user access.

If you don't do this, then it would be a race condition vulnerability.

Rook
No. SQLite3 commands like ATTACH can access other files. Not worried about race condition, since SQLite3 has locking.
barrycarter
@user354134 Yes race conditions are still a **very large** issue in the scenario I described. If you are are locking the file on the file system, there is a gap when the file is unlocked and you aren't accessing it with sqlite. But you are right about attach, i'm not sure a good way to handle that without trying to parse the query.
Rook
+1  A: 

Of course, if I knew all such commands, I'd just filter against them, but I'm mostly worried about commands I haven't thought of.

Have you considered using a whitelist instead of a blacklist? Only allow statements that start with SELECT or EXPLAIN.

dan04
sqllite allows for query stacking...
Rook
Yes, but *you* don't have to allow it. Instead of sqlite3_exec, use prepared statements, which execute only one statement at a time.
dan04
@dan04 A user writing queries is the exact opposite of prepared statements.
Rook
I think I'm OK w/o multiple queries in one go, but I'm still worried about nested queries. However, if the file's read-only, that may be OK. I'll check if SQLite3 responds to "SELECT * FROM (ATTACH ...)" type queries.I'm also worried about (for example) semicolons that'll make sqlite run multiple queries anyway. Of course, I can filter against semicolons, but you get the general idea.
barrycarter
A: 

Assure that your user has write access and that other users (especially the user that the webserver runs as) has only read access to the file itself. How you do this of course depends on your platform (Linux, Windows, etc.)

Pete
Right. That part's easy. The hard part: what sqlite3 commands can access other files (eg, ATTACH).
barrycarter
A: 

Make your database file read only in the operating system. Once you've done that SQLite can't override it. If you still have issues it's not a SQLite issue. They might still be able to find a php/cgi/etc issue but that's the nature of the security beast.

Jay
Unfortunately, not true (that was my original plan). Commands like ATTACH can access other files.
barrycarter
If your environment doesn't allow access to other files there's not a lot they can do with it. Can you run it in a chroot jail?
Jay