diff options
author | Lukas Reschke <lukas@owncloud.com> | 2016-02-25 17:19:24 +0100 |
---|---|---|
committer | Lukas Reschke <lukas@owncloud.com> | 2016-02-25 17:54:27 +0100 |
commit | 5780ba611e6db84719e709b3fe03d08fd8ef58f0 (patch) | |
tree | 7a4c623c61799e4eb138319f2ef7e279db6c1c0f /build/integration | |
parent | 3772a8acdb611b441bf2ea4fa3e0a37110a9d69f (diff) | |
download | nextcloud-server-5780ba611e6db84719e709b3fe03d08fd8ef58f0.tar.gz nextcloud-server-5780ba611e6db84719e709b3fe03d08fd8ef58f0.zip |
Add integration test for CSRF protection on DAV
This adds the integration tests for the CSRF protection on the DAV backend introduced with 9.0.
Fixes https://github.com/owncloud/core/issues/22598
Diffstat (limited to 'build/integration')
-rw-r--r-- | build/integration/features/bootstrap/BasicStructure.php | 92 | ||||
-rw-r--r-- | build/integration/features/webdav-related.feature | 37 |
2 files changed, 127 insertions, 2 deletions
diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php index bf3b1d50814..0084597836f 100644 --- a/build/integration/features/bootstrap/BasicStructure.php +++ b/build/integration/features/bootstrap/BasicStructure.php @@ -7,7 +7,7 @@ use GuzzleHttp\Message\ResponseInterface; require __DIR__ . '/../../vendor/autoload.php'; -trait BasicStructure{ +trait BasicStructure { /** @var string */ private $currentUser = ''; @@ -20,6 +20,12 @@ trait BasicStructure{ /** @var ResponseInterface */ private $response = null; + /** @var \GuzzleHttp\Cookie\CookieJar */ + private $cookieJar; + + /** @var string */ + private $requesttoken; + public function __construct($baseUrl, $admin, $regular_user_password) { // Initialize your context here @@ -29,6 +35,7 @@ trait BasicStructure{ $this->localBaseUrl = substr($this->baseUrl, 0, -4); $this->remoteBaseUrl = substr($this->baseUrl, 0, -4); $this->currentServer = 'LOCAL'; + $this->cookieJar = new \GuzzleHttp\Cookie\CookieJar(); // in case of ci deployment we take the server url from the environment $testServerUrl = getenv('TEST_SERVER_URL'); @@ -93,7 +100,6 @@ trait BasicStructure{ /** * @When /^sending "([^"]*)" to "([^"]*)" with$/ - * @param \Behat\Gherkin\Node\TableNode|null $formData */ public function sendingToWith($verb, $url, $body) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php" . $url; @@ -136,6 +142,88 @@ trait BasicStructure{ PHPUnit_Framework_Assert::assertEquals($statusCode, $this->response->getStatusCode()); } + /** + * @param ResponseInterface $response + */ + private function extracRequestTokenFromResponse(ResponseInterface $response) { + $this->requesttoken = substr(preg_replace('/(.*)data-requesttoken="(.*)">(.*)/sm', '\2', $response->getBody()->getContents()), 0, 89); + } + + /** + * @Given Logging in using web as :user + */ + public function loggingInUsingWebAs($user) { + $loginUrl = substr($this->baseUrl, 0, -5); + // Request a new session and extract CSRF token + $client = new Client(); + $response = $client->get( + $loginUrl, + [ + 'cookies' => $this->cookieJar, + ] + ); + $this->extracRequestTokenFromResponse($response); + + // Login and extract new token + $password = ($user === 'admin') ? 'admin' : '123456'; + $client = new Client(); + $response = $client->post( + $loginUrl, + [ + 'body' => [ + 'user' => $user, + 'password' => $password, + 'requesttoken' => $this->requesttoken, + ], + 'cookies' => $this->cookieJar, + ] + ); + $this->extracRequestTokenFromResponse($response); + } + + /** + * @When Sending a :method to :url with requesttoken + */ + public function sendingAToWithRequesttoken($method, $url) { + $baseUrl = substr($this->baseUrl, 0, -5); + + $client = new Client(); + $request = $client->createRequest( + $method, + $baseUrl . $url, + [ + 'cookies' => $this->cookieJar, + ] + ); + $request->addHeader('requesttoken', $this->requesttoken); + try { + $this->response = $client->send($request); + } catch (\GuzzleHttp\Exception\ClientException $e) { + $this->response = $e->getResponse(); + } + } + + /** + * @When Sending a :method to :url without requesttoken + */ + public function sendingAToWithoutRequesttoken($method, $url) { + $baseUrl = substr($this->baseUrl, 0, -5); + + $client = new Client(); + $request = $client->createRequest( + $method, + $baseUrl . $url, + [ + 'cookies' => $this->cookieJar, + ] + ); + try { + $this->response = $client->send($request); + } catch (\GuzzleHttp\Exception\ClientException $e) { + $this->response = $e->getResponse(); + } + } + public static function removeFile($path, $filename){ if (file_exists("$path" . "$filename")) { unlink("$path" . "$filename"); diff --git a/build/integration/features/webdav-related.feature b/build/integration/features/webdav-related.feature index c424f77afd5..0d2cefa8b80 100644 --- a/build/integration/features/webdav-related.feature +++ b/build/integration/features/webdav-related.feature @@ -62,9 +62,46 @@ Feature: sharing |X-XSS-Protection|1; mode=block| And Downloaded content should start with "Welcome to your ownCloud account!" + Scenario: Doing a GET with a web login should work without CSRF token on the nwe backend + Given Logging in using web as "admin" + When Sending a "GET" to "/remote.php/dav/files/admin/welcome.txt" without requesttoken + Then Downloaded content should start with "Welcome to your ownCloud account!" + Then the HTTP status code should be "200" + Scenario: Doing a GET with a web login should work with CSRF token on the new backend + Given Logging in using web as "admin" + When Sending a "GET" to "/remote.php/dav/files/admin/welcome.txt" with requesttoken + Then Downloaded content should start with "Welcome to your ownCloud account!" + Then the HTTP status code should be "200" + Scenario: Doing a PROPFIND with a web login should not work without CSRF token on the new backend + Given Logging in using web as "admin" + When Sending a "PROPFIND" to "/remote.php/dav/files/admin/welcome.txt" without requesttoken + Then the HTTP status code should be "401" + Scenario: Doing a PROPFIND with a web login should work with CSRF token on the new backend + Given Logging in using web as "admin" + When Sending a "PROPFIND" to "/remote.php/dav/files/admin/welcome.txt" with requesttoken + Then the HTTP status code should be "207" + Scenario: Doing a GET with a web login should work without CSRF token on the old backend + Given Logging in using web as "admin" + When Sending a "GET" to "/remote.php/webdav/welcome.txt" without requesttoken + Then Downloaded content should start with "Welcome to your ownCloud account!" + Then the HTTP status code should be "200" + Scenario: Doing a GET with a web login should work with CSRF token on the old backend + Given Logging in using web as "admin" + When Sending a "GET" to "/remote.php/webdav/welcome.txt" with requesttoken + Then Downloaded content should start with "Welcome to your ownCloud account!" + Then the HTTP status code should be "200" + Scenario: Doing a PROPFIND with a web login should not work without CSRF token on the old backend + Given Logging in using web as "admin" + When Sending a "PROPFIND" to "/remote.php/webdav/welcome.txt" without requesttoken + Then the HTTP status code should be "401" + + Scenario: Doing a PROPFIND with a web login should work with CSRF token on the old backend + Given Logging in using web as "admin" + When Sending a "PROPFIND" to "/remote.php/webdav/welcome.txt" with requesttoken + Then the HTTP status code should be "207" |