summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Reschke <lukas@owncloud.com>2015-10-06 14:18:46 +0200
committerLukas Reschke <lukas@owncloud.com>2015-10-06 14:18:46 +0200
commit80a232da6a5470e248979cfde7b1e4e2237b8284 (patch)
treee62ee54d82c00aa4da11a5716e24ad25c2d939b0
parent4b31b349b876bef5ef1839add20017b9ad048447 (diff)
downloadnextcloud-server-80a232da6a5470e248979cfde7b1e4e2237b8284.tar.gz
nextcloud-server-80a232da6a5470e248979cfde7b1e4e2237b8284.zip
Add \OCP\IRequest::getHttpProtocol
Only allow valid HTTP protocols. Ref https://github.com/owncloud/core/pull/19537#discussion_r41252333 + https://github.com/owncloud/security-tracker/issues/119
-rw-r--r--lib/private/appframework/http/request.php21
-rw-r--r--lib/public/irequest.php8
-rw-r--r--tests/lib/appframework/http/RequestTest.php51
3 files changed, 80 insertions, 0 deletions
diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php
index 29414b92f7c..cfd903bffe5 100644
--- a/lib/private/appframework/http/request.php
+++ b/lib/private/appframework/http/request.php
@@ -553,6 +553,27 @@ class Request implements \ArrayAccess, \Countable, IRequest {
}
/**
+ * Returns the used HTTP protocol.
+ *
+ * @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0.
+ */
+ public function getHttpProtocol() {
+ $claimedProtocol = strtoupper($this->server['SERVER_PROTOCOL']);
+
+ $validProtocols = [
+ 'HTTP/1.0',
+ 'HTTP/1.1',
+ 'HTTP/2',
+ ];
+
+ if(in_array($claimedProtocol, $validProtocols, true)) {
+ return $claimedProtocol;
+ }
+
+ return 'HTTP/1.1';
+ }
+
+ /**
* Returns the request uri, even if the website uses one or more
* reverse proxies
* @return string
diff --git a/lib/public/irequest.php b/lib/public/irequest.php
index 20fa543dd69..acfc4f3f1d0 100644
--- a/lib/public/irequest.php
+++ b/lib/public/irequest.php
@@ -168,6 +168,14 @@ interface IRequest {
public function getServerProtocol();
/**
+ * Returns the used HTTP protocol.
+ *
+ * @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0.
+ * @since 8.2.0
+ */
+ public function getHttpProtocol();
+
+ /**
* Returns the request uri, even if the website uses one or more
* reverse proxies
* @return string
diff --git a/tests/lib/appframework/http/RequestTest.php b/tests/lib/appframework/http/RequestTest.php
index e9a0755d1f8..f75e4578546 100644
--- a/tests/lib/appframework/http/RequestTest.php
+++ b/tests/lib/appframework/http/RequestTest.php
@@ -497,6 +497,57 @@ class RequestTest extends \Test\TestCase {
$this->assertSame('192.168.0.233', $request->getRemoteAddress());
}
+ /**
+ * @return array
+ */
+ public function httpProtocolProvider() {
+ return [
+ // Valid HTTP 1.0
+ ['HTTP/1.0', 'HTTP/1.0'],
+ ['http/1.0', 'HTTP/1.0'],
+ ['HTTp/1.0', 'HTTP/1.0'],
+
+ // Valid HTTP 1.1
+ ['HTTP/1.1', 'HTTP/1.1'],
+ ['http/1.1', 'HTTP/1.1'],
+ ['HTTp/1.1', 'HTTP/1.1'],
+
+ // Valid HTTP 2.0
+ ['HTTP/2', 'HTTP/2'],
+ ['http/2', 'HTTP/2'],
+ ['HTTp/2', 'HTTP/2'],
+
+ // Invalid
+ ['HTTp/394', 'HTTP/1.1'],
+ ['InvalidProvider/1.1', 'HTTP/1.1'],
+ [null, 'HTTP/1.1'],
+ ['', 'HTTP/1.1'],
+
+ ];
+ }
+
+ /**
+ * @dataProvider httpProtocolProvider
+ *
+ * @param mixed $input
+ * @param string $expected
+ */
+ public function testGetHttpProtocol($input, $expected) {
+ $request = new Request(
+ [
+ 'server' => [
+ 'SERVER_PROTOCOL' => $input,
+ ],
+ ],
+ $this->secureRandom,
+ $this->getMock('\OCP\Security\ICrypto'),
+ $this->config,
+ $this->stream
+ );
+
+ $this->assertSame($expected, $request->getHttpProtocol());
+ }
+
public function testGetServerProtocolWithOverride() {
$this->config
->expects($this->at(0))