diff options
author | Bernhard Posselt <Raydiation@users.noreply.github.com> | 2014-05-11 16:54:34 +0200 |
---|---|---|
committer | Bernhard Posselt <Raydiation@users.noreply.github.com> | 2014-05-11 16:54:34 +0200 |
commit | a252f59cd436d2c005755955bc93ab44544df766 (patch) | |
tree | 75e0e94cf98c70e9941d8856520e8ac63b670230 /lib/private | |
parent | b6d76e9985105a245daf63f60b47e82df283019d (diff) | |
parent | e05192a23d11867a9860ac6e38e372e21919a861 (diff) | |
download | nextcloud-server-a252f59cd436d2c005755955bc93ab44544df766.tar.gz nextcloud-server-a252f59cd436d2c005755955bc93ab44544df766.zip |
Merge pull request #8504 from owncloud/cors-middleware
Add cors middleware
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/appframework/dependencyinjection/dicontainer.php | 6 | ||||
-rw-r--r-- | lib/private/appframework/middleware/security/corsmiddleware.php | 72 |
2 files changed, 78 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..e32c5d42875 --- /dev/null +++ b/lib/private/appframework/middleware/security/corsmiddleware.php @@ -0,0 +1,72 @@ +<?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 IRequest $request + */ + 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; + } + + +} |