1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
From: Nicolas Grekas <nicolas.grekas@gmail.com>
Date: Fri, 18 May 2018 09:42:46 +0200
Subject: [HttpFoundation] Break infinite loop in PdoSessionHandler when MySQL
is in loose mode
[CVE-2018-11386] https://symfony.com/blog/cve-2018-11386-denial-of-service-when-using-pdosessionhandler
Origin: backport, https://github.com/symfony/symfony/commit/0cf874e23e12cad4e3546de10aa793e5fe8a31f0
---
.../HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
index 48e81ee..27b2c0c 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
@@ -510,6 +510,7 @@ class PdoSessionHandler implements \SessionHandlerInterface
$selectSql = $this->getSelectSql();
$selectStmt = $this->pdo->prepare($selectSql);
$selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
+ $insertStmt = null;
$selectStmt->execute();
$sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM);
@@ -524,6 +525,11 @@ class PdoSessionHandler implements \SessionHandlerInterface
return is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0];
}
+ if (null !== $insertStmt) {
+ $this->rollback();
+ throw new \RuntimeException('Failed to read session: INSERT reported a duplicate id but next SELECT did not return any data.');
+ }
+
if (self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) {
// Exclusive-reading of non-existent rows does not block, so we need to do an insert to block
// until other connections to the session are committed.
|