diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index 6a99a7e342b..374e5f6b810 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -9,6 +9,7 @@ private import implementations.Iterator private import implementations.MemberFunction private import implementations.Memcpy private import implementations.Memset +private import implementations.ODBC private import implementations.Printf private import implementations.Pure private import implementations.Strcat diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/ODBC.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/ODBC.qll new file mode 100644 index 00000000000..cd470621b34 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/ODBC.qll @@ -0,0 +1,30 @@ +/** + * Provides implementation classes modeling the ODBC C/C++ API. + * See `semmle.code.cpp.models.Models` for usage information. + */ + +private import semmle.code.cpp.models.interfaces.Sql +private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs + +/** + * The `SQLExecDirect`, and `SQLPrepare` from the ODBC C/C++ API: + * https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecdirect-function?view=sql-server-ver16 + * https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprepare-function?view=sql-server-ver16 + * + * Note, `SQLExecute` is not included because it operates on a SQLHSTMT type, not a string. + * The SQLHSTMT parameter for `SQLExecute` is set through a `SQLPrepare`, which is modeled. + * The other source of input to a `SQLExecute` is via a `SQLBindParameter`, which sanitizes user input, + * and would be considered a barrier to SQL injection. + */ +private class ODBCExecutionFunction extends SqlExecutionFunction { + ODBCExecutionFunction() { + exists(string s | s in ["SQLExecDirect", "SQLPrepare"] and this.hasName(s)) + } + + override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) } +} +// NOTE: no need to define a barrier explicitly. +// `SQLBindParameter` is the typical means for sanitizing user input. +// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindparameter-function?view=sql-server-ver16 +// First a query is establisehed via `SQLPrepare`, then parameters are bound via `SQLBindParameter`, before +// the query is executed via `SQLExecute`. We are not modeling SQLExecute, so we do not need to model SQLBindParameter.