The authorizer is used to protect against SQL injection attaches
when the SQL text originates from user input.  Typically an
application will turn the authorizer on when preparing user-supplied
SQL then turn it right back off again so that its own internal
SQL can run unfiltered.  Example:

   sqlite3_set_authorizer(db, ignore_passwd_column);
   stmt1 = sqlite3_prepare(db, zSqlFromUser)
   sqlite3_set_authorizer(db, 0);
   stmt2 = sqlite3_prepare(db, zInternalSql);
   sqlite3_step(stmt1);  --  Oops!  Might try to recompile!

Note also that the authorizer will not necessary throw an error
the first time.  It might just cause certain columns in a table
to be ignored.  For example, in the CVSTrac system (used for
bug tracking on SQLite as well as elsewhere) user-generated
ticket reports can query any table in the database.  But if
the report requests the USER.PASSWD field, the authorizer causes
that field to return a NULL rather than the actual user password.
No error is generated so there is nothing to signal a problem
the first time the authorizer is run.  But if the statement
is then recompiled automatically with the authorizer turned
off, then the PASSWD information might leak through.
I see. So in order to re-prepare an SQL statement you would need to keep a copy of the authorizer callback pointer that was used when it was originally prepared. Couldn't this be done automatically as well?

Perhaps it could be made more explicit by adding an authorizer callback parameter to a new sqlite3_prepare_v2() function. This function could also include an SQL string destructor argument that could be used to eliminate most SQL string copies as well.

This all starts to feel a bit "unsafe". What would happen if a program
would load a library that houses the callback and it gets unloaded
after the first prepare? Or is it a rule you need to have the callback
available for the entire run of the virtual machine?

Rob

Reply via email to