├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json └── src ├── ConfigProvider.php ├── CsrfGuardFactoryInterface.php ├── CsrfGuardInterface.php ├── CsrfMiddleware.php ├── CsrfMiddlewareFactory.php ├── Exception ├── ExceptionInterface.php ├── MissingFlashMessagesException.php └── MissingSessionException.php ├── FlashCsrfGuard.php ├── FlashCsrfGuardFactory.php ├── SessionCsrfGuard.php └── SessionCsrfGuardFactory.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file, in reverse chronological order by release. 4 | 5 | ## 1.0.2 - TBD 6 | 7 | ### Added 8 | 9 | - Nothing. 10 | 11 | ### Changed 12 | 13 | - Nothing. 14 | 15 | ### Deprecated 16 | 17 | - Nothing. 18 | 19 | ### Removed 20 | 21 | - Nothing. 22 | 23 | ### Fixed 24 | 25 | - Nothing. 26 | 27 | ## 1.0.1 - 2019-06-24 28 | 29 | ### Added 30 | 31 | - [#9](https://github.com/zendframework/zend-expressive-csrf/pull/9) adds support for PHP 7.3. 32 | 33 | ### Changed 34 | 35 | - Nothing. 36 | 37 | ### Deprecated 38 | 39 | - Nothing. 40 | 41 | ### Removed 42 | 43 | - Nothing. 44 | 45 | ### Fixed 46 | 47 | - Nothing. 48 | 49 | ## 1.0.0 - 2018-03-15 50 | 51 | ### Added 52 | 53 | - [#5](https://github.com/zendframework/zend-expressive-csrf/pull/5) adds 54 | support for PSR-15. 55 | 56 | ### Changed 57 | 58 | - Updates minimum supported versions of both zend-expressive-session and 59 | zend-expressive-flash to 1.0.0. 60 | 61 | ### Deprecated 62 | 63 | - Nothing. 64 | 65 | ### Removed 66 | 67 | - [#5](https://github.com/zendframework/zend-expressive-csrf/pull/5) and 68 | [#3](https://github.com/zendframework/zend-expressive-csrf/pull/3) remove 69 | support for http-interop/http-middleware and 70 | http-interop/http-server-middleware. 71 | 72 | ### Fixed 73 | 74 | - Nothing. 75 | 76 | ## 0.1.1 - 2017-10-11 77 | 78 | ### Added 79 | 80 | - Nothing. 81 | 82 | ### Changed 83 | 84 | - Nothing. 85 | 86 | ### Deprecated 87 | 88 | - Nothing. 89 | 90 | ### Removed 91 | 92 | - Nothing. 93 | 94 | ### Fixed 95 | 96 | - Fixes the `ConfigProvider` to correctly use the `SessionCsrfGuardFactory` as 97 | the default `CsrfGuardFactoryInterface` implementation; this ensures that no 98 | additional dependencies are required to use the extension initially. 99 | 100 | ## 0.1.0 - 2017-10-10 101 | 102 | ### Added 103 | 104 | - Everything. 105 | 106 | ### Changed 107 | 108 | - Nothing. 109 | 110 | ### Deprecated 111 | 112 | - Nothing. 113 | 114 | ### Removed 115 | 116 | - Nothing. 117 | 118 | ### Fixed 119 | 120 | - Nothing. 121 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2018, Zend Technologies USA, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | - Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | - Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | - Neither the name of Zend Technologies USA, Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from this 16 | software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zend-expressive-csrf 2 | 3 | > ## Repository abandoned 2019-12-31 4 | > 5 | > This repository has moved to [mezzio/mezzio-csrf](https://github.com/mezzio/mezzio-csrf). 6 | 7 | [![Build Status](https://secure.travis-ci.org/zendframework/zend-expressive-csrf.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-expressive-csrf) 8 | [![Coverage Status](https://coveralls.io/repos/github/zendframework/zend-expressive-csrf/badge.svg?branch=master)](https://coveralls.io/github/zendframework/zend-expressive-csrf?branch=master) 9 | 10 | Provides CSRF token generation and validation for PSR-7 applications, using 11 | [zend-expressive-session](https://docs.zendframework.com/zend-expressive-session), 12 | and optionally [zend-expressive-flash](https://docs.zendframework.com/zend-expressive-flash). 13 | 14 | ## Installation 15 | 16 | Run the following to install this library: 17 | 18 | ```bash 19 | $ composer require zendframework/zend-expressive-csrf 20 | ``` 21 | 22 | ## Documentation 23 | 24 | Documentation is [in the doc tree](docs/book/), and can be compiled using [mkdocs](http://www.mkdocs.org): 25 | 26 | ```bash 27 | $ mkdocs build 28 | ``` 29 | 30 | You may also [browse the documentation online](https://docs.zendframework.com/zend-expressive-csrf/). 31 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zendframework/zend-expressive-csrf", 3 | "description": "CSRF token generation and validation for PSR-7 and PSR-15 applications using zend-expressive-session", 4 | "license": "BSD-3-Clause", 5 | "keywords": [ 6 | "csrf", 7 | "expressive", 8 | "psr-7", 9 | "psr-15", 10 | "security", 11 | "session", 12 | "zf", 13 | "zendframework", 14 | "zend-expressive" 15 | ], 16 | "support": { 17 | "docs": "https://docs.zendframework.com/zend-expressive-csrf/", 18 | "issues": "https://github.com/zendframework/zend-expressive-csrf/issues", 19 | "source": "https://github.com/zendframework/zend-expressive-csrf", 20 | "rss": "https://github.com/zendframework/zend-expressive-csrf/releases.atom", 21 | "slack": "https://zendframework-slack.herokuapp.com", 22 | "forum": "https://discourse.zendframework.com/c/questions/expressive" 23 | }, 24 | "require": { 25 | "php": "^7.1", 26 | "psr/container": "^1.0", 27 | "psr/http-server-middleware": "^1.0", 28 | "zendframework/zend-expressive-session": "^1.0" 29 | }, 30 | "require-dev": { 31 | "phpunit/phpunit": "^7.0.2", 32 | "zendframework/zend-coding-standard": "~1.0.0", 33 | "zendframework/zend-expressive-flash": "^1.0" 34 | }, 35 | "conflict": { 36 | "phpspec/prophecy": "<1.7.2" 37 | }, 38 | "suggest": { 39 | "zendframework/zend-expressive-flash": "^1.0.0alpha1 || ^1.0 To back CSRF tokens using flash messages" 40 | }, 41 | "autoload": { 42 | "psr-4": { 43 | "Zend\\Expressive\\Csrf\\": "src/" 44 | } 45 | }, 46 | "autoload-dev": { 47 | "psr-4": { 48 | "ZendTest\\Expressive\\Csrf\\": "test/" 49 | } 50 | }, 51 | "config": { 52 | "sort-packages": true 53 | }, 54 | "extra": { 55 | "branch-alias": { 56 | "dev-master": "1.0.x-dev", 57 | "dev-develop": "1.1.x-dev" 58 | }, 59 | "zf": { 60 | "config-provider": "Zend\\Expressive\\Csrf\\ConfigProvider" 61 | } 62 | }, 63 | "scripts": { 64 | "check": [ 65 | "@cs-check", 66 | "@test" 67 | ], 68 | "cs-check": "phpcs", 69 | "cs-fix": "phpcbf", 70 | "test": "phpunit --colors=always", 71 | "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/ConfigProvider.php: -------------------------------------------------------------------------------- 1 | $this->getDependencies(), 18 | ]; 19 | } 20 | 21 | public function getDependencies() : array 22 | { 23 | return [ 24 | 'aliases' => [ 25 | // Change this to the CsrfGuardFactoryInterface implementation you wish to use: 26 | CsrfGuardFactoryInterface::class => SessionCsrfGuardFactory::class, 27 | ], 28 | 'invokables' => [ 29 | FlashCsrfGuardFactory::class => FlashCsrfGuardFactory::class, 30 | SessionCsrfGuardFactory::class => SessionCsrfGuardFactory::class, 31 | ], 32 | 'factories' => [ 33 | CsrfMiddleware::class => CsrfMiddlewareFactory::class, 34 | ], 35 | ]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/CsrfGuardFactoryInterface.php: -------------------------------------------------------------------------------- 1 | guardFactory = $guardFactory; 46 | $this->attributeKey = $attributeKey; 47 | } 48 | 49 | public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface 50 | { 51 | $guard = $this->guardFactory->createGuardFromRequest($request); 52 | return $handler->handle($request->withAttribute($this->attributeKey, $guard)); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/CsrfMiddlewareFactory.php: -------------------------------------------------------------------------------- 1 | get(CsrfGuardFactoryInterface::class) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Exception/ExceptionInterface.php: -------------------------------------------------------------------------------- 1 | flashMessages = $flashMessages; 27 | } 28 | 29 | public function generateToken(string $keyName = '__csrf') : string 30 | { 31 | $token = bin2hex(random_bytes(16)); 32 | $this->flashMessages->flash($keyName, $token); 33 | return $token; 34 | } 35 | 36 | public function validateToken(string $token, string $csrfKey = '__csrf') : bool 37 | { 38 | $storedToken = $this->flashMessages->getFlash($csrfKey, ''); 39 | return $token === $storedToken; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/FlashCsrfGuardFactory.php: -------------------------------------------------------------------------------- 1 | attributeKey = $attributeKey; 26 | } 27 | 28 | public function createGuardFromRequest(ServerRequestInterface $request) : CsrfGuardInterface 29 | { 30 | $flashMessages = $request->getAttribute($this->attributeKey, false); 31 | if (! $flashMessages instanceof FlashMessagesInterface) { 32 | throw Exception\MissingFlashMessagesException::create(); 33 | } 34 | 35 | return new FlashCsrfGuard($flashMessages); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/SessionCsrfGuard.php: -------------------------------------------------------------------------------- 1 | session = $session; 27 | } 28 | 29 | public function generateToken(string $keyName = '__csrf') : string 30 | { 31 | $token = bin2hex(random_bytes(16)); 32 | $this->session->set($keyName, $token); 33 | return $token; 34 | } 35 | 36 | public function validateToken(string $token, string $csrfKey = '__csrf') : bool 37 | { 38 | $storedToken = $this->session->get($csrfKey, ''); 39 | $this->session->unset($csrfKey); 40 | return $token === $storedToken; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/SessionCsrfGuardFactory.php: -------------------------------------------------------------------------------- 1 | attributeKey = $attributeKey; 26 | } 27 | 28 | public function createGuardFromRequest(ServerRequestInterface $request) : CsrfGuardInterface 29 | { 30 | $session = $request->getAttribute($this->attributeKey, false); 31 | if (! $session instanceof SessionInterface) { 32 | throw Exception\MissingSessionException::create(); 33 | } 34 | 35 | return new SessionCsrfGuard($session); 36 | } 37 | } 38 | --------------------------------------------------------------------------------