diff options
author | Bernhard Posselt <dev@bernhard-posselt.com> | 2014-05-08 11:47:18 +0200 |
---|---|---|
committer | Bernhard Posselt <dev@bernhard-posselt.com> | 2014-05-09 23:34:41 +0200 |
commit | 9a4d204b55da063631f01a780d32b3fd88c729cd (patch) | |
tree | 63d4905af6945ef4c0a8f350a3d85ed8d9d0e391 /lib/private/appframework | |
parent | af2b7634eeb8c3bd8ec5dec8b600fbaf8ae5d498 (diff) | |
download | nextcloud-server-9a4d204b55da063631f01a780d32b3fd88c729cd.tar.gz nextcloud-server-9a4d204b55da063631f01a780d32b3fd88c729cd.zip |
add cors middleware
remove methodannotationreader namespace
fix namespace for server container
fix tests
fail if with cors credentials header is set to true, implement a reusable preflighted cors method in the controller baseclass, make corsmiddleware private and register it for every request
remove uneeded local in cors middleware registratio
dont uppercase cors to easily use it from routes
fix indention
comment fixes
explicitely set allow credentials header to false
dont depend on better controllers PR, fix that stuff later
split cors methods to be in a seperate controller for exposing apis
remove protected definitions from apicontroller since controller has it
Diffstat (limited to 'lib/private/appframework')
-rw-r--r-- | lib/private/appframework/dependencyinjection/dicontainer.php | 6 | ||||
-rw-r--r-- | lib/private/appframework/middleware/security/corsmiddleware.php | 73 |
2 files changed, 79 insertions, 0 deletions
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php index e478225a53d..becd755bda7 100644 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ b/lib/private/appframework/dependencyinjection/dicontainer.php @@ -30,6 +30,7 @@ use OC\AppFramework\Http\Dispatcher; use OC\AppFramework\Core\API; use OC\AppFramework\Middleware\MiddlewareDispatcher; use OC\AppFramework\Middleware\Security\SecurityMiddleware; +use OC\AppFramework\Middleware\Security\CORSMiddleware; use OC\AppFramework\Utility\SimpleContainer; use OC\AppFramework\Utility\TimeFactory; use OCP\AppFramework\IApi; @@ -92,10 +93,15 @@ class DIContainer extends SimpleContainer implements IAppContainer{ return new SecurityMiddleware($app, $c['Request']); }); + $this['CORSMiddleware'] = $this->share(function($c) { + return new CORSMiddleware($c['Request']); + }); + $middleWares = &$this->middleWares; $this['MiddlewareDispatcher'] = $this->share(function($c) use (&$middleWares) { $dispatcher = new MiddlewareDispatcher(); $dispatcher->registerMiddleware($c['SecurityMiddleware']); + $dispatcher->registerMiddleware($c['CORSMiddleware']); foreach($middleWares as $middleWare) { $dispatcher->registerMiddleware($c[$middleWare]); diff --git a/lib/private/appframework/middleware/security/corsmiddleware.php b/lib/private/appframework/middleware/security/corsmiddleware.php new file mode 100644 index 00000000000..1049b3ed473 --- /dev/null +++ b/lib/private/appframework/middleware/security/corsmiddleware.php @@ -0,0 +1,73 @@ +<?php +/** + * ownCloud - App Framework + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Bernhard Posselt <dev@bernhard-posselt.com> + * @copyright Bernhard Posselt 2014 + */ + +namespace OC\AppFramework\Middleware\Security; + +use OC\AppFramework\Utility\MethodAnnotationReader; +use OCP\IRequest; +use OCP\AppFramework\Http\Response; +use OCP\AppFramework\Middleware; + +/** + * This middleware sets the correct CORS headers on a response if the + * controller has the @CORS annotation. This is needed for webapps that want + * to access an API and dont run on the same domain, see + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS + */ +class CORSMiddleware extends Middleware { + + private $request; + + /** + * @param string $request the name of the method that will be called on + * the controller + */ + public function __construct(IRequest $request) { + $this->request = $request; + } + + + /** + * This is being run after a successful controllermethod call and allows + * the manipulation of a Response object. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param Response $response the generated response from the controller + * @return Response a Response object + */ + public function afterController($controller, $methodName, Response $response){ + // only react if its a CORS request and if the request sends origin and + $reflector = new MethodAnnotationReader($controller, $methodName); + + if(isset($this->request->server['HTTP_ORIGIN']) && + $reflector->hasAnnotation('CORS')) { + + // allow credentials headers must not be true or CSRF is possible + // otherwise + foreach($response->getHeaders() as $header => $value ) { + if(strtolower($header) === 'access-control-allow-credentials' && + strtolower(trim($value)) === 'true') { + $msg = 'Access-Control-Allow-Credentials must not be '. + 'set to true in order to prevent CSRF'; + throw new SecurityException($msg); + } + } + + $origin = $this->request->server['HTTP_ORIGIN']; + $response->addHeader('Access-Control-Allow-Origin', $origin); + } + return $response; + } + + +} |