getPhpcsOutputForGitBatch() (ShellRunner.php:441) and getPhpcsOutputForSvnBatch() (ShellRunner.php:478) both do:
$tempDir = sys_get_temp_dir() . '/phpcs-changed-' . uniqid();
mkdir($tempDir);
and writeTempFile() (ShellRunner.php:339) does:
if (! is_dir($dir)) {
mkdir($dir, 0777, true);
}
Three problems:
- Unchecked
mkdir() return value. If the directory already exists, mkdir() emits a warning and returns false, and the code proceeds to write into it anyway.
- Predictable name.
uniqid() is derived from the current microtime and is guessable. On a shared machine (CI runner, shared build box) another local user can pre-create the predicted path and plant new/ and old/ as symlinks. Since the failed mkdir() is ignored, the cmd > tempfile redirect in writeCommandOutputToFile() then writes git/svn file contents through the symlink, or lets the attacker tamper with the temp copies before the single batched phpcs run reads them (forged lint results on a commit gate).
- Permissive mode.
0777 & ~umask on the directories, plus default file permissions, transiently expose copies of the scanned source to other local users.
CWE-377 (insecure temporary file) / CWE-378 (creation of temp file with insecure permissions).
Suggested fix
Create the root temp dir with mode 0700 and check the return value, failing loudly if it is already taken; use random_bytes()-derived entropy rather than uniqid(); use 0700 for the nested directories in writeTempFile() too and check that return value as well.
getPhpcsOutputForGitBatch()(ShellRunner.php:441) andgetPhpcsOutputForSvnBatch()(ShellRunner.php:478) both do:and
writeTempFile()(ShellRunner.php:339) does:Three problems:
mkdir()return value. If the directory already exists,mkdir()emits a warning and returnsfalse, and the code proceeds to write into it anyway.uniqid()is derived from the current microtime and is guessable. On a shared machine (CI runner, shared build box) another local user can pre-create the predicted path and plantnew/andold/as symlinks. Since the failedmkdir()is ignored, thecmd > tempfileredirect inwriteCommandOutputToFile()then writes git/svn file contents through the symlink, or lets the attacker tamper with the temp copies before the single batched phpcs run reads them (forged lint results on a commit gate).0777 & ~umaskon the directories, plus default file permissions, transiently expose copies of the scanned source to other local users.CWE-377 (insecure temporary file) / CWE-378 (creation of temp file with insecure permissions).
Suggested fix
Create the root temp dir with mode
0700and check the return value, failing loudly if it is already taken; userandom_bytes()-derived entropy rather thanuniqid(); use0700for the nested directories inwriteTempFile()too and check that return value as well.