Bug #73611 Exception when data object (dict) contains string with existing field name
Submitted: 16 Aug 2014 11:53 Modified: 22 Mar 2017 18:25
Reporter: Сергей Столяров Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / Python Severity:S2 (Serious)
Version:1.2.2 OS:Any
Assigned to: CPU Architecture:Any

[16 Aug 2014 11:53] Сергей Столяров
Description:
When data object contains string that contains reference to another existing field, then query sometimes crashes.

To reproduce execute script from the section “How to repeat”

How to repeat:
import mysql.connector
cnx = mysql.connector.connect(user='test', password='test',
    host='10.10.13.38',
    database='test')
cursor = cnx.cursor()

try:
    cursor.execute('CREATE TABLE test (f1 TEXT, f2 TEXT, f3 TEXT)')
except mysql.connector.errors.ProgrammingError:
    pass

query = 'INSERT INTO test VALUES (%(f1)s, %(f2)s, %(f3)s)'
data = {
    'f1': 'xxx %(f3)s yyy',
    'f2': 'xxx %(f2)s yyy',
    'f3': 'xxx %(f1)s yyy'
}
cursor.execute(query, data)

cnx.close()

Suggested fix:
Cause of the problem in this piece of code (file mysql/connector/cursor.py):

 497         if params is not None:
 498             if isinstance(params, dict):
 499                 for key, value in self._process_params_dict(params).items():
 500                     stmt = stmt.replace(key, value)
 501             elif isinstance(params, (list, tuple)):
 502                 psub = _ParamSubstitutor(self._process_params(params))
 503                 stmt = RE_PY_PARAM.sub(psub, stmt)
 504                 if psub.remaining != 0:
 505                     raise errors.ProgrammingError(
 506                         "Not all parameters were used in the SQL statement")

Look at the line 500.
[16 Aug 2014 11:55] Сергей Столяров
Forgot to attach error message:

mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxx %(f1)s yyy' yyy', 'xxx %(f2)s yyy', 'xxx %(f1)s yyy')' at line 1
[22 Aug 2014 8:24] Peeyush Gupta
Thanks for the bug report.

Verified as described through code analysis.
[22 Mar 2017 18:25] Paul DuBois
Posted by developer:
 
Noted in 2.1.4 changelog.

A potential SQL injection vector was eliminated.