As seen on https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1176470:
includes/libs/rdbms/querybuilder/UpdateQueryBuilder.php:332 SecurityCheck-SQLInjection Calling method \Wikimedia\Rdbms\IDatabase::update() in \Wikimedia\Rdbms\UpdateQueryBuilder::execute that outputs using tainted argument #3 (`$this->conds`). (Caused by: annotations in \Wikimedia\Rdbms\IDatabase::update) (Caused by: includes/jobqueue/JobQueueDB.php +744; includes/jobqueue/JobQueueDB.php +732; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchResultSet; includes/jobqueue/JobQueueDB.php +753; includes/jobqueue/JobQueueDB.php +382; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchRow; includes/jobqueue/JobQueueDB.php +406; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchRow; includes/jobqueue/JobQueueDB.php +428; maintenance/updateCollation.php +443; maintenance/updateCollation.php +442; maintenance/updateCollation.php +429; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchResultSet; maintenance/updateCollation.php +445; includes/filerepo/file/LocalFile.php +812; includes/filerepo/file/LocalFile.php +809; includes/filerepo/file/LocalFile.php +800; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; includes/filerepo/file/LocalFileMoveBatch.php +405; includes/filerepo/file/LocalFileMoveBatch.php +383; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; includes/filerepo/file/LocalFileMoveBatch.php +399; includes/filerepo/file/LocalFile.php +812; includes/filerepo/file/LocalFile.php +809; includes/filerepo/file/LocalFile.php +800; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; includes/filerepo/file/LocalFileDeleteBatch.php +338; includes/filerepo/file/LocalFileDeleteBatch.php +150; includes/filerepo/file/LocalFileDeleteBatch.php +141; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchResultSet; includes/filerepo/file/LocalFileDeleteBatch.php +163; includes/filerepo/file/LocalFile.php +825; includes/filerepo/file/LocalFile.php +823; includes/filerepo/file/LocalFile.php +812; includes/filerepo/file/LocalFile.php +809; includes/filerepo/file/LocalFile.php +800; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; includes/filerepo/file/LocalFile.php +858; includes/filerepo/file/LocalFile.php +827; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; includes/filerepo/file/OldLocalFile.php +343; includes/filerepo/file/LocalFile.php +1969; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; includes/filerepo/file/LocalFile.php +2045; includes/filerepo/file/LocalFile.php +812; includes/filerepo/file/LocalFile.php +809; includes/filerepo/file/LocalFile.php +800; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; includes/filerepo/file/LocalFile.php +1993; includes/filerepo/file/LocalFile.php +827; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; includes/filerepo/file/LocalFile.php +853; includes/jobqueue/utils/PurgeJobUtils.php +77; includes/jobqueue/utils/PurgeJobUtils.php +76; includes/jobqueue/utils/PurgeJobUtils.php +61; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchFieldValues; includes/jobqueue/utils/PurgeJobUtils.php +78; includes/auth/LocalPasswordPrimaryAuthenticationProvider.php +118; includes/auth/LocalPasswordPrimaryAuthenticationProvider.php +106; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchRow; includes/auth/LocalPasswordPrimaryAuthenticationProvider.php +122; includes/auth/LocalPasswordPrimaryAuthenticationProvider.php +106; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchRow; includes/auth/LocalPasswordPrimaryAuthenticationProvider.php +149; includes/watchlist/ClearWatchlistNotificationsJob.php +76; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchFieldValues; includes/watchlist/ClearWatchlistNotificationsJob.php +86; includes/RenameUser/Job/RenameUserTableJob.php +109; includes/RenameUser/Job/RenameUserTableJob.php +103; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchFieldValues; includes/RenameUser/Job/RenameUserTableJob.php +112; includes/filerepo/file/LocalFile.php +825; includes/filerepo/file/LocalFile.php +823; includes/filerepo/file/LocalFile.php +812; includes/filerepo/file/LocalFile.php +809; includes/filerepo/file/LocalFile.php +800; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; includes/filerepo/file/LocalFile.php +858; includes/filerepo/file/LocalFile.php +827; annotations in \Wikimedia\Rdbms\SelectQueryBuilder::fetchField; ...)
Incomprehensible error message aside (what is it even trying to list?), one thing that makes this seem like a bug in SecurityCheck (and not a real issue with the code being analyzed) is the fact that $this->conds is somehow tainted while in execute(), but there are no other error messages. The only assignments to $this->conds are in where(), and if the values being assigned are tainted, that should generate a SecurityCheck error on the where() call that passes them.
I tried to do some debugging on this, but I didn't get far. I learned two things though:
- Commenting-out this line in where() makes the error disappear: https://gerrit.wikimedia.org/g/mediawiki/core/+/277d4b025d8327fbfedabf09fa3e2ea8b096ffea/includes/libs/rdbms/querybuilder/UpdateQueryBuilder.php#210 $this->conds[$key] = $cond;
- @phan-debug-var-taintedness in execute() gives: SecurityCheckDebugTaintedness Variable $conds has taintedness: {Own: NONE; Keys: YES; Elements: {UNKNOWN => {Own: YES; Elements: {cat_title => {Own: YES}; ...(20+ other keys here)... job_token => {Own: NONE}; UNKNOWN => {Own: YES}}}}} – clearly it is the Keys: YES that is the problem, and that part goes away when commenting out that aforementioned line. I haven't found a way to figure out where this taint comes from. The taints for individual array elements don't matter, I wonder if it's even good to track them here?