|
| 1 | +/** |
| 2 | + * Provides implementation classes modeling the ODBC C/C++ API. |
| 3 | + * See `semmle.code.cpp.models.Models` for usage information. |
| 4 | + */ |
| 5 | + |
| 6 | +private import semmle.code.cpp.models.interfaces.Sql |
| 7 | +private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs |
| 8 | + |
| 9 | +/** |
| 10 | + * The `SQLExecDirect`, and `SQLPrepare` from the ODBC C/C++ API: |
| 11 | + * https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecdirect-function?view=sql-server-ver16 |
| 12 | + * https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprepare-function?view=sql-server-ver16 |
| 13 | + * |
| 14 | + * Note, `SQLExecute` is not included because it operates on a SQLHSTMT type, not a string. |
| 15 | + * The SQLHSTMT parameter for `SQLExecute` is set through a `SQLPrepare`, which is modeled. |
| 16 | + * The other source of input to a `SQLExecute` is via a `SQLBindParameter`, which sanitizes user input, |
| 17 | + * and would be considered a barrier to SQL injection. |
| 18 | + */ |
| 19 | +private class ODBCExecutionFunction extends SqlExecutionFunction { |
| 20 | + ODBCExecutionFunction() { |
| 21 | + exists(string s | s in ["SQLExecDirect", "SQLPrepare"] and this.hasName(s)) |
| 22 | + } |
| 23 | + |
| 24 | + override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) } |
| 25 | +} |
| 26 | +// NOTE: no need to define a barrier explicitly. |
| 27 | +// `SQLBindParameter` is the typical means for sanitizing user input. |
| 28 | +// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindparameter-function?view=sql-server-ver16 |
| 29 | +// First a query is establisehed via `SQLPrepare`, then parameters are bound via `SQLBindParameter`, before |
| 30 | +// the query is executed via `SQLExecute`. We are not modeling SQLExecute, so we do not need to model SQLBindParameter. |
0 commit comments