Skip to content

Commit b67e5cb

Browse files
security #cve-2019-10913 [HttpFoundation] reject invalid method override (nicolas-grekas)
This PR was merged into the 2.7 branch. Discussion ---------- [HttpFoundation] reject invalid method override | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - From https://www.intigriti.com/company/submission/CfDJ8Pja6NZvkpNCmx5vVyiGSn7LV-k0ZJ4JlDGSPAaBG1sG1aNinWbVYRos8ldmLPCMSPdHLrwLufz8lXoJ-UNS3XW1_Xkxc7u9rIaENVJ_-nQV_uic7D1tmRhB6PFiBkRgBA About `Request::getMethod`: > There will be developers, who expect the http method to be valid and therefore will use the return value unescaped in sql, html or other dangerous places. this is what this PR improves, forcing only ASCII letters in overridden methods. > It is possible to set the header to "GET", "HEAD", "OPTIONS" and "TRACE". Because of this, the method Request::isMethodSafe() returns true, although the actual http method is post. I don't think this creates any issue: not fixed. > Normally, if you try to provide a request body in a GET-Request, the web server discards the request body. This security functionality can be completely bypassed through this. [...] Recommendation: Remove the parsed body params from the request object, if a method without a body is set. I don't think this is valid: actually we *do* populate `$request->request` with the body of GET requests when some is sent. > Even if very rare, some users still use old browsers, where CORS is not available. Or a server admin allowed headers to be cross origin. In those cases this functionality enables CSRF-Attackes, if the developers trusts the http method. (E.g. Shopware does this). I don't understand this, not addressed. ping @michaelcullum if you want to answer the person. And other to review :) Commits ------- 6ce9991392 [HttpFoundation] reject invalid method override
1 parent e8eb43e commit b67e5cb

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

Request.php

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,19 +1290,37 @@ public function setMethod($method)
12901290
*/
12911291
public function getMethod()
12921292
{
1293-
if (null === $this->method) {
1294-
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
1295-
1296-
if ('POST' === $this->method) {
1297-
if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
1298-
$this->method = strtoupper($method);
1299-
} elseif (self::$httpMethodParameterOverride) {
1300-
$this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
1301-
}
1302-
}
1293+
if (null !== $this->method) {
1294+
return $this->method;
1295+
}
1296+
1297+
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
1298+
1299+
if ('POST' !== $this->method) {
1300+
return $this->method;
1301+
}
1302+
1303+
$method = $this->headers->get('X-HTTP-METHOD-OVERRIDE');
1304+
1305+
if (!$method && self::$httpMethodParameterOverride) {
1306+
$method = $this->request->get('_method', $this->query->get('_method', 'POST'));
1307+
}
1308+
1309+
if (!\is_string($method)) {
1310+
return $this->method;
1311+
}
1312+
1313+
$method = strtoupper($method);
1314+
1315+
if (\in_array($method, array('GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'PATCH', 'PURGE', 'TRACE'), true)) {
1316+
return $this->method = $method;
1317+
}
1318+
1319+
if (!preg_match('/^[A-Z]++$/D', $method)) {
1320+
throw new \UnexpectedValueException(sprintf('Invalid method override "%s".', $method));
13031321
}
13041322

1305-
return $this->method;
1323+
return $this->method = $method;
13061324
}
13071325

13081326
/**

0 commit comments

Comments
 (0)