MXS-2457 Allow string arguments to be treated as fields

Before this change, the masking could be bypassed simply by

    > set @@sql_mode='ANSI_QUOTES';
    > select concat("ssn") from person;

The reason is that as the query classifier is not aware of whether
'ANSI_QUOTES' is on or not, it will not know that what above appears
to be the string "ssn", actually is the field name `ssn`. Consequently,
the select will not be blocked and the result returned in cleartext.

It's now possible to instruct the query classifier to report all string
arguments of functions as fields, which will prevent the above. However,
it will also mean that there may be false positives.
This commit is contained in:
Johan Wikman
2019-05-02 14:19:44 +03:00
parent 09d04a09d4
commit f09d46c8e6
4 changed files with 146 additions and 5 deletions

View File

@ -96,9 +96,11 @@ class QCInfoCache;
static thread_local struct
{
QCInfoCache* pInfo_cache;
uint32_t options;
} this_thread =
{
nullptr
nullptr,
0
};
@ -147,7 +149,8 @@ public:
{
const Entry& entry = i->second;
if (entry.sql_mode == this_unit.qc_sql_mode)
if ((entry.sql_mode == this_unit.qc_sql_mode) &&
(entry.options == this_thread.options))
{
mxb_assert(this_unit.classifier);
this_unit.classifier->qc_info_dup(entry.pInfo);
@ -157,7 +160,7 @@ public:
}
else
{
// If the sql_mode has changed, we discard the existing result.
// If the sql_mode or options has changed, we discard the existing result.
erase(i);
++m_stats.misses;
@ -197,7 +200,7 @@ public:
{
this_unit.classifier->qc_info_dup(pInfo);
m_infos.emplace(canonical_stmt, Entry(pInfo, this_unit.qc_sql_mode));
m_infos.emplace(canonical_stmt, Entry(pInfo, this_unit.qc_sql_mode, this_thread.options));
++m_stats.inserts;
m_stats.size += size;
@ -213,14 +216,16 @@ public:
private:
struct Entry
{
Entry(QC_STMT_INFO* pInfo, qc_sql_mode_t sql_mode)
Entry(QC_STMT_INFO* pInfo, qc_sql_mode_t sql_mode, uint32_t options)
: pInfo(pInfo)
, sql_mode(sql_mode)
, options(options)
{
}
QC_STMT_INFO* pInfo;
qc_sql_mode_t sql_mode;
uint32_t options;
};
typedef std::unordered_map<std::string, Entry> InfosByStmt;
@ -1282,6 +1287,29 @@ void qc_set_sql_mode(qc_sql_mode_t sql_mode)
}
}
uint32_t qc_get_options()
{
QC_TRACE();
mxb_assert(this_unit.classifier);
return this_unit.classifier->qc_get_options();
}
bool qc_set_options(uint32_t options)
{
QC_TRACE();
mxb_assert(this_unit.classifier);
int32_t rv = this_unit.classifier->qc_set_options(options);
if (rv == QC_RESULT_OK)
{
this_thread.options = options;
}
return rv == QC_RESULT_OK;
}
void qc_get_cache_properties(QC_CACHE_PROPERTIES* properties)
{
properties->max_size = this_unit.cache_max_size();