From b578083f08ae2e3e0eb2dc45d332525971ffe901 Mon Sep 17 00:00:00 2001 From: Kentaro Ohkouchi Date: Wed, 2 Dec 2020 19:01:59 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=83=BC=E3=83=A9=E3=81=AE=20URL=20=E3=83=81=E3=82=A7=E3=83=83?= =?UTF-8?q?=E3=82=AF=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controller/Install/InstallController.php | 188 +++++++++++++++++- 1 file changed, 178 insertions(+), 10 deletions(-) diff --git a/src/Eccube/Controller/Install/InstallController.php b/src/Eccube/Controller/Install/InstallController.php index bb93fd5720f..a62240c9196 100644 --- a/src/Eccube/Controller/Install/InstallController.php +++ b/src/Eccube/Controller/Install/InstallController.php @@ -41,15 +41,34 @@ use Eccube\Service\SystemService; use Eccube\Util\CacheUtil; use Eccube\Util\StringUtil; +use Jose\Component\Checker\AudienceChecker; +use Jose\Component\Checker\ClaimCheckerManager; +use Jose\Component\Checker\ExpirationTimeChecker; +use Jose\Component\Checker\InvalidClaimException; +use Jose\Component\Checker\IssuedAtChecker; +use Jose\Component\Checker\NotBeforeChecker; +use Jose\Component\Core\AlgorithmManager; +use Jose\Component\Core\JWK; +use Jose\Component\KeyManagement\JWKFactory; +use Jose\Component\Signature\Algorithm\RS256; +use Jose\Component\Signature\JWS; +use Jose\Component\Signature\JWSBuilder; +use Jose\Component\Signature\JWSVerifier; +use Jose\Component\Signature\Serializer\CompactSerializer; +use Jose\Component\Signature\Serializer\JWSSerializerManager; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class InstallController extends AbstractController { @@ -58,6 +77,11 @@ class InstallController extends AbstractController */ const DEFAULT_AUTH_MAGIC = ''; + /** @var string */ + const JWK_PUBLIC = 'public_jwk.json'; + /** @var string */ + const JWK_PRIVATE = 'private_jwk.json'; + protected $requiredModules = [ 'pdo', 'phar', @@ -105,6 +129,11 @@ class InstallController extends AbstractController */ protected $cacheUtil; + /** + * @var string + */ + protected $jwksDir; + public function __construct(PasswordEncoder $encoder, CacheUtil $cacheUtil) { $this->encoder = $encoder; @@ -503,15 +532,21 @@ public function complete(Request $request) $this->removeSessionData($this->session); - // FIXME: installで設定したsessionをprodで参照できない - $this->session->set('install.plugin_enable_ok', true); + // 有効化URLを保護するための Cookie を生成する + $jwk = $this->createJwks(); + $algorithmManager = $this->getAlgorithmManager(); + $payload = $this->createPayload('install.plugin_enable_ok'); + $token = $this->createJWSToken($payload); + $cookie = Cookie::create('ECINSTALLER_TRANSACTION', $token, 0, $this->generateUrl('install', [], UrlGeneratorInterface::ABSOLUTE_URL)); + $response = $this->render('complete.twig', [ + 'admin_url' => $adminUrl, + 'plugin_enable_url' => $pluginEnableUrl, + ]); + $response->headers->setCookie($cookie); $this->cacheUtil->clearCache('prod'); - return [ - 'admin_url' => $adminUrl, - 'plugin_enable_url' => $pluginEnableUrl, - ]; + return $response; } /** @@ -525,10 +560,30 @@ public function complete(Request $request) */ public function pluginEnable(Plugin $Plugin, CacheUtil $cacheUtil, SystemService $systemService, PluginService $pluginService) { - // FIXME: installで設定したsessionをprodで参照できない -// if (!$this->session->get('install.plugin_enable_ok', false)) { -// throw new BadRequestHttpException(); -// } + // 有効化URLを保護するための Cookie をチェックする + $jws = $this->unserializeToken($_COOKIE['ECINSTALLER_TRANSACTION']); + $verifier = new JWSVerifier($this->getAlgorithmManager()); + if ($verifier->verifyWithKey($jws, $this->getPublicJWK(), 0) === false) { + throw new AccessDeniedHttpException('bad transaction signeture'); + } + $payload = json_decode($jws->getPayload(), true); + try { + $claimCheckerManager = new ClaimCheckerManager( + [ + new IssuedAtChecker(), + new NotBeforeChecker(), + new ExpirationTimeChecker(), + new AudienceChecker($this->generateUrl('install', [], UrlGeneratorInterface::ABSOLUTE_URL)), + ] + ); + $claim = $claimCheckerManager->check($payload); + } catch (InvalidClaimException $e) { + throw new AccessDeniedHttpException($e->getMessage()); + } + + if ($payload[$this->generateUrl('install', [], UrlGeneratorInterface::ABSOLUTE_URL).'/transaction'] !== 'install.plugin_enable_ok') { + throw new AccessDeniedHttpException('bad transaction '); + } $systemService->switchMaintenance(true); // auto_maintenanceと設定されたファイルを生成 $systemService->disableMaintenance(SystemService::AUTO_MAINTENANCE); @@ -1116,4 +1171,117 @@ protected function isInstallEnv() return false; } + + /** + * @return string + */ + private function getJwksDir() + { + $projectDir = $this->getParameter('kernel.project_dir'); + return $projectDir.'/var/cache/install/jwks'; + } + + /** + * @return JWK + */ + private function createJwks() + { + $jwksDir = $this->getJwksDir(); + if (!file_exists($jwksDir.'/'.self::JWK_PRIVATE) && !file_exists($jwksDir.'/'.self::JWK_PUBLIC)) { + if (!file_exists($this->jwksDir)) { + mkdir($this->jwksDir, 0755, true); + } + + $jwk = JWKFactory::createRSAKey( + 4096, + [ + 'alg' => 'RS256', + 'use' => 'sig' + ] + ); + $publicKey = $jwk->toPublic(); + $jwk_private = json_encode($jwk->jsonSerialize()); + $jwk_public = json_encode($publicKey->jsonSerialize()); + file_put_contents($jwksDir.'/'.self::JWK_PRIVATE, $jwk_private); + file_put_contents($jwksDir.'/'.self::JWK_PUBLIC, $jwk_public); + } + + return JWKFactory::createFromJsonObject(file_get_contents($jwksDir.'/'.self::JWK_PRIVATE)); + } + + /** + * @return JWK + */ + private function getPublicJWK() + { + $jwksDir = $this->getJwksDir(); + + return JWKFactory::createFromJsonObject(file_get_contents($jwksDir.'/'.self::JWK_PUBLIC)); + } + + /** + * @return JWK + */ + private function getPrivateJWK() + { + $jwksDir = $this->getJwksDir(); + + return JWKFactory::createFromJsonObject(file_get_contents($jwksDir.'/'.self::JWK_PRIVATE)); + } + + /** + * @return AlgorithmManager + */ + private function getAlgorithmManager() + { + return new AlgorithmManager( + [new RS256()] + ); + } + + /** + * @var string + */ + private function createPayload($transaction) + { + return json_encode([ + 'iat' => time(), + 'nbf' => time(), + 'exp' => time() + (60 * 10), + 'iss' => $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL), + 'aud' => $this->generateUrl('install', [], UrlGeneratorInterface::ABSOLUTE_URL), + $this->generateUrl('install', [], UrlGeneratorInterface::ABSOLUTE_URL).'/transaction' => $transaction + ]); + } + + /** + * @param string $payload + * @return string + */ + private function createJWSToken($payload) + { + $jwsBuilder = new JWSBuilder(null, $this->getAlgorithmManager()); + $jws = $jwsBuilder->create() + ->withPayload($payload) + ->addSignature($this->getPrivateJWK(), ['alg' => 'RS256']) + ->build(); + + $manager = JWSSerializerManager::create( + [new CompactSerializer()] + ); + + return $manager->serialize('jws_compact', $jws, 0); + } + + /** + * @return JWS + */ + private function unserializeToken($token) + { + $manager = JWSSerializerManager::create( + [new CompactSerializer()] + ); + + return $manager->unserialize($token); + } } From 33036a33dd0bedafc8bebbdf972a9479ff443989 Mon Sep 17 00:00:00 2001 From: Kentaro Ohkouchi Date: Thu, 3 Dec 2020 09:17:09 +0900 Subject: [PATCH 2/3] Add web-token/jwt-framework --- composer.json | 3 +- composer.lock | 455 +++++++++++++++++++++++++++++++++++++++++++++++++- symfony.lock | 15 ++ 3 files changed, 471 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 06e49f87ca5..0397e9f31d2 100644 --- a/composer.json +++ b/composer.json @@ -103,7 +103,8 @@ "tecnickcom/tcpdf": "^6.2", "twig/extensions": "^1.5", "twig/twig": "^2.4", - "vlucas/phpdotenv": "v2.4.0" + "vlucas/phpdotenv": "v2.4.0", + "web-token/jwt-framework": "^1.3" }, "require-dev": { "bheller/images-generator": "^1.0", diff --git a/composer.lock b/composer.lock index 2972c6a6abd..1f037ff3f26 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a5f2fb902ef18e3b7b04cc137be59f37", + "content-hash": "5f5e232cf7fed2f94a7fde2792946302", "packages": [ { "name": "composer/ca-bundle", @@ -2138,6 +2138,81 @@ }, "time": "2020-09-26T15:48:38+00:00" }, + { + "name": "fgrosse/phpasn1", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/fgrosse/PHPASN1.git", + "reference": "d1978f7abd580f3fc33561e7f71d4c12c7531fad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/d1978f7abd580f3fc33561e7f71d4c12c7531fad", + "reference": "d1978f7abd580f3fc33561e7f71d4c12c7531fad", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.3", + "satooshi/php-coveralls": "~2.0" + }, + "suggest": { + "ext-bcmath": "BCmath is the fallback extension for big integer calculations", + "ext-curl": "For loading OID information from the web if they have not bee defined statically", + "ext-gmp": "GMP is the preferred extension for big integer calculations", + "phpseclib/bcmath_compat": "BCmath polyfill for servers where neither GMP nor BCmath is available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "FG\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Friedrich Große", + "email": "friedrich.grosse@gmail.com", + "homepage": "https://github.com/FGrosse", + "role": "Author" + }, + { + "name": "All contributors", + "homepage": "https://github.com/FGrosse/PHPASN1/contributors" + } + ], + "description": "A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules.", + "homepage": "https://github.com/FGrosse/PHPASN1", + "keywords": [ + "DER", + "asn.1", + "asn1", + "ber", + "binary", + "decoding", + "encoding", + "x.509", + "x.690", + "x509", + "x690" + ], + "support": { + "issues": "https://github.com/fgrosse/PHPASN1/issues", + "source": "https://github.com/fgrosse/PHPASN1/tree/v2.2.0" + }, + "time": "2020-10-11T16:28:18+00:00" + }, { "name": "friendsofphp/php-cs-fixer", "version": "v2.16.7", @@ -3154,6 +3229,92 @@ }, "time": "2018-07-02T15:55:56+00:00" }, + { + "name": "paragonie/sodium_compat", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/sodium_compat.git", + "reference": "bbade402cbe84c69b718120911506a3aa2bae653" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/bbade402cbe84c69b718120911506a3aa2bae653", + "reference": "bbade402cbe84c69b718120911506a3aa2bae653", + "shasum": "" + }, + "require": { + "paragonie/random_compat": ">=1", + "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^3|^4|^5|^6|^7" + }, + "suggest": { + "ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.", + "ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security." + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com" + }, + { + "name": "Frank Denis", + "email": "jedisct1@pureftpd.org" + } + ], + "description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists", + "keywords": [ + "Authentication", + "BLAKE2b", + "ChaCha20", + "ChaCha20-Poly1305", + "Chapoly", + "Curve25519", + "Ed25519", + "EdDSA", + "Edwards-curve Digital Signature Algorithm", + "Elliptic Curve Diffie-Hellman", + "Poly1305", + "Pure-PHP cryptography", + "RFC 7748", + "RFC 8032", + "Salpoly", + "Salsa20", + "X25519", + "XChaCha20-Poly1305", + "XSalsa20-Poly1305", + "Xchacha20", + "Xsalsa20", + "aead", + "cryptography", + "ecdh", + "elliptic curve", + "elliptic curve cryptography", + "encryption", + "libsodium", + "php", + "public-key cryptography", + "secret-key cryptography", + "side-channel resistant" + ], + "support": { + "issues": "https://github.com/paragonie/sodium_compat/issues", + "source": "https://github.com/paragonie/sodium_compat/tree/v1.13.0" + }, + "time": "2020-03-20T21:48:09+00:00" + }, { "name": "php-cs-fixer/diff", "version": "v1.3.0", @@ -3961,6 +4122,134 @@ }, "time": "2020-01-29T21:12:37+00:00" }, + { + "name": "spomky-labs/aes-key-wrap", + "version": "v5.0.0", + "source": { + "type": "git", + "url": "https://github.com/Spomky-Labs/aes-key-wrap.git", + "reference": "7e5c5bef68a08d0c474e6ff6d5b63d12e023b3b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Spomky-Labs/aes-key-wrap/zipball/7e5c5bef68a08d0c474e6ff6d5b63d12e023b3b2", + "reference": "7e5c5bef68a08d0c474e6ff6d5b63d12e023b3b2", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "lib-openssl": "*", + "php": "^7.1" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "AESKW\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky-Labs/aes-key-wrap/contributors" + } + ], + "description": "AES Key Wrap for PHP.", + "homepage": "https://github.com/Spomky-Labs/aes-key-wrap", + "keywords": [ + "A128KW", + "A192KW", + "A256KW", + "RFC3394", + "RFC5649", + "aes", + "key", + "padding", + "wrap" + ], + "support": { + "issues": "https://github.com/Spomky-Labs/aes-key-wrap/issues", + "source": "https://github.com/Spomky-Labs/aes-key-wrap/tree/master" + }, + "time": "2018-07-23T10:32:27+00:00" + }, + { + "name": "spomky-labs/base64url", + "version": "v2.0.4", + "source": { + "type": "git", + "url": "https://github.com/Spomky-Labs/base64url.git", + "reference": "7752ce931ec285da4ed1f4c5aa27e45e097be61d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Spomky-Labs/base64url/zipball/7752ce931ec285da4ed1f4c5aa27e45e097be61d", + "reference": "7752ce931ec285da4ed1f4c5aa27e45e097be61d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.11|^0.12", + "phpstan/phpstan-beberlei-assert": "^0.11|^0.12", + "phpstan/phpstan-deprecation-rules": "^0.11|^0.12", + "phpstan/phpstan-phpunit": "^0.11|^0.12", + "phpstan/phpstan-strict-rules": "^0.11|^0.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "Base64Url\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky-Labs/base64url/contributors" + } + ], + "description": "Base 64 URL Safe Encoding/Decoding PHP Library", + "homepage": "https://github.com/Spomky-Labs/base64url", + "keywords": [ + "base64", + "rfc4648", + "safe", + "url" + ], + "support": { + "issues": "https://github.com/Spomky-Labs/base64url/issues", + "source": "https://github.com/Spomky-Labs/base64url/tree/v2.0.4" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2020-11-03T09:10:25+00:00" + }, { "name": "suncat/mobile-detect-bundle", "version": "v1.1.1", @@ -9778,6 +10067,170 @@ }, "time": "2016-09-01T10:05:43+00:00" }, + { + "name": "web-token/jwt-framework", + "version": "v1.3.10", + "source": { + "type": "git", + "url": "https://github.com/web-token/jwt-framework.git", + "reference": "49289f26906d40d3fef23c5ddbba5f24347bb56a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-token/jwt-framework/zipball/49289f26906d40d3fef23c5ddbba5f24347bb56a", + "reference": "49289f26906d40d3fef23c5ddbba5f24347bb56a", + "shasum": "" + }, + "require": { + "ext-gmp": "*", + "ext-mbstring": "*", + "fgrosse/phpasn1": "^2.0", + "lib-openssl": "*", + "paragonie/sodium_compat": "^1.2", + "php": "^7.1", + "spomky-labs/aes-key-wrap": "^4.0.1|^5.0", + "spomky-labs/base64url": "^1.0|^2.0", + "symfony/config": "^3.4|^4.0", + "symfony/console": "^3.4|^4.0", + "symfony/dependency-injection": "^3.4|^4.0", + "symfony/framework-bundle": "^3.4|^4.0", + "symfony/http-kernel": "^3.4|^4.0" + }, + "conflict": { + "spomky-labs/jose": "*" + }, + "replace": { + "web-token/jwt-bundle": "self.version", + "web-token/jwt-checker": "self.version", + "web-token/jwt-console": "self.version", + "web-token/jwt-core": "self.version", + "web-token/jwt-encryption": "self.version", + "web-token/jwt-encryption-algorithm-aescbc": "self.version", + "web-token/jwt-encryption-algorithm-aesgcm": "self.version", + "web-token/jwt-encryption-algorithm-aesgcmkw": "self.version", + "web-token/jwt-encryption-algorithm-aeskw": "self.version", + "web-token/jwt-encryption-algorithm-dir": "self.version", + "web-token/jwt-encryption-algorithm-ecdh-es": "self.version", + "web-token/jwt-encryption-algorithm-experimental": "self.version", + "web-token/jwt-encryption-algorithm-pbes2": "self.version", + "web-token/jwt-encryption-algorithm-rsa": "self.version", + "web-token/jwt-key-mgmt": "self.version", + "web-token/jwt-signature": "self.version", + "web-token/jwt-signature-algorithm-ecdsa": "self.version", + "web-token/jwt-signature-algorithm-eddsa": "self.version", + "web-token/jwt-signature-algorithm-experimental": "self.version", + "web-token/jwt-signature-algorithm-hmac": "self.version", + "web-token/jwt-signature-algorithm-none": "self.version", + "web-token/jwt-signature-algorithm-rsa": "self.version", + "web-token/jwt-util-ecc": "self.version" + }, + "require-dev": { + "bjeavons/zxcvbn-php": "^0.4.0", + "blackfire/php-sdk": "^1.14", + "ext-curl": "*", + "guzzlehttp/psr7": "^1.4", + "matthiasnoback/symfony-config-test": "^3.1|^4.0", + "php-coveralls/php-coveralls": "^2.0", + "php-http/httplug-bundle": "^1.7", + "php-http/mock-client": "^1.0", + "phpunit/phpunit": "^7.5", + "symfony/browser-kit": "^3.4|^4.0", + "symfony/finder": "^3.4|^4.0", + "symfony/phpunit-bridge": "^3.4|^4.0", + "symfony/serializer": "^3.3|^4.0", + "symfony/yaml": "^3.4|^4.0" + }, + "suggest": { + "bjeavons/zxcvbn-php": "Adds key quality check for oct keys.", + "php-http/httplug": "To enable JKU/X5U support.", + "php-http/httplug-bundle": "To enable JKU/X5U support.", + "php-http/message-factory": "To enable JKU/X5U support.", + "symfony/serializer": "Use the Symfony serializer to serialize/unserialize JWS and JWE tokens." + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jose\\": "src/", + "Jose\\Tests\\": "tests/", + "Jose\\Component\\Signature\\Algorithm\\": [ + "src/SignatureAlgorithm/ECDSA", + "src/SignatureAlgorithm/EdDSA", + "src/SignatureAlgorithm/HMAC", + "src/SignatureAlgorithm/None", + "src/SignatureAlgorithm/RSA", + "src/SignatureAlgorithm/Experimental" + ], + "Jose\\Component\\Core\\Util\\Ecc\\": [ + "src/Ecc" + ], + "Jose\\Component\\Encryption\\Algorithm\\": [ + "src/EncryptionAlgorithm/Experimental" + ], + "Jose\\Component\\Encryption\\Algorithm\\KeyEncryption\\": [ + "src/EncryptionAlgorithm/KeyEncryption/AESGCMKW", + "src/EncryptionAlgorithm/KeyEncryption/AESKW", + "src/EncryptionAlgorithm/KeyEncryption/Direct", + "src/EncryptionAlgorithm/KeyEncryption/ECDHES", + "src/EncryptionAlgorithm/KeyEncryption/PBES2", + "src/EncryptionAlgorithm/KeyEncryption/RSA" + ], + "Jose\\Component\\Encryption\\Algorithm\\ContentEncryption\\": [ + "src/EncryptionAlgorithm/ContentEncryption/AESGCM", + "src/EncryptionAlgorithm/ContentEncryption/AESCBC" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/web-token/jwt-framework/contributors" + } + ], + "description": "JSON Object Signing and Encryption library for PHP and Symfony Bundle.", + "homepage": "https://github.com/web-token/jwt-framework", + "keywords": [ + "JOSE", + "JWE", + "JWK", + "JWKSet", + "JWS", + "Jot", + "RFC7515", + "RFC7516", + "RFC7517", + "RFC7518", + "RFC7519", + "RFC7520", + "bundle", + "jwa", + "jwt", + "symfony" + ], + "support": { + "issues": "https://github.com/web-token/jwt-framework/issues", + "source": "https://github.com/web-token/jwt-framework/tree/v1.3" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + } + ], + "time": "2020-03-27T12:22:14+00:00" + }, { "name": "zendframework/zend-code", "version": "3.4.1", diff --git a/symfony.lock b/symfony.lock index 273d24df3ec..ddfae580a64 100644 --- a/symfony.lock +++ b/symfony.lock @@ -131,6 +131,9 @@ "facebook/webdriver": { "version": "1.5.0" }, + "fgrosse/phpasn1": { + "version": "v2.2.0" + }, "friendsofphp/php-cs-fixer": { "version": "2.2", "recipe": { @@ -194,6 +197,9 @@ "paragonie/random_compat": { "version": "v2.0.11" }, + "paragonie/sodium_compat": { + "version": "v1.13.0" + }, "phar-io/manifest": { "version": "1.0.1" }, @@ -341,6 +347,12 @@ "skorp/detect-incompatible-samesite-useragents": { "version": "1.0.0" }, + "spomky-labs/aes-key-wrap": { + "version": "v5.0.0" + }, + "spomky-labs/base64url": { + "version": "v2.0.4" + }, "suncat/mobile-detect-bundle": { "version": "1.0", "recipe": { @@ -665,6 +677,9 @@ "vlucas/phpdotenv": { "version": "v2.4.0" }, + "web-token/jwt-framework": { + "version": "v1.3.10" + }, "webmozart/assert": { "version": "1.3.0" }, From f00b858063f4b5ca245a37d2de7f293bd1a6810c Mon Sep 17 00:00:00 2001 From: Kentaro Ohkouchi Date: Thu, 3 Dec 2020 10:26:30 +0900 Subject: [PATCH 3/3] =?UTF-8?q?cookie=20=E9=96=A2=E9=80=A3=E3=81=AE?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controller/Install/InstallController.php | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Eccube/Controller/Install/InstallController.php b/src/Eccube/Controller/Install/InstallController.php index a62240c9196..191307a4054 100644 --- a/src/Eccube/Controller/Install/InstallController.php +++ b/src/Eccube/Controller/Install/InstallController.php @@ -498,10 +498,11 @@ public function complete(Request $request) $databaseUrl = $this->createDatabaseUrl($sessionData); $mailerUrl = $this->createMailerUrl($sessionData); $forceSSL = isset($sessionData['admin_force_ssl']) ? (bool) $sessionData['admin_force_ssl'] : false; + $forceSSLString = 'false'; if ($forceSSL === false) { - $forceSSL = 'false'; + $forceSSLString = 'false'; } elseif ($forceSSL === true) { - $forceSSL = 'true'; + $forceSSLString = 'true'; } $env = file_get_contents(__DIR__.'/../../../../.env.dist'); $replacement = [ @@ -512,7 +513,7 @@ public function complete(Request $request) 'ECCUBE_AUTH_MAGIC' => $sessionData['authmagic'], 'DATABASE_SERVER_VERSION' => isset($sessionData['database_version']) ? $sessionData['database_version'] : '3', 'ECCUBE_ADMIN_ALLOW_HOSTS' => $this->convertAdminAllowHosts($sessionData['admin_allow_hosts']), - 'ECCUBE_FORCE_SSL' => $forceSSL, + 'ECCUBE_FORCE_SSL' => $forceSSLString, 'ECCUBE_ADMIN_ROUTE' => isset($sessionData['admin_dir']) ? $sessionData['admin_dir'] : 'admin', 'ECCUBE_COOKIE_PATH' => $request->getBasePath() ? $request->getBasePath() : '/', 'ECCUBE_TEMPLATE_CODE' => 'default', @@ -537,11 +538,14 @@ public function complete(Request $request) $algorithmManager = $this->getAlgorithmManager(); $payload = $this->createPayload('install.plugin_enable_ok'); $token = $this->createJWSToken($payload); - $cookie = Cookie::create('ECINSTALLER_TRANSACTION', $token, 0, $this->generateUrl('install', [], UrlGeneratorInterface::ABSOLUTE_URL)); + $cookie = Cookie::create('ECINSTALLER_TRANSACTION', $token, 0, $this->generateUrl('install', [], UrlGeneratorInterface::ABSOLUTE_URL), $request->getHost(), $forceSSL); + setcookie('ECINSTALLER_TRANSACTION', $token); // FIXME Symfony cookie が保存されないため暫定措置 + $response = $this->render('complete.twig', [ 'admin_url' => $adminUrl, 'plugin_enable_url' => $pluginEnableUrl, ]); + $response->headers->setCookie($cookie); $this->cacheUtil->clearCache('prod'); @@ -561,7 +565,10 @@ public function complete(Request $request) public function pluginEnable(Plugin $Plugin, CacheUtil $cacheUtil, SystemService $systemService, PluginService $pluginService) { // 有効化URLを保護するための Cookie をチェックする - $jws = $this->unserializeToken($_COOKIE['ECINSTALLER_TRANSACTION']); + if (!$request->cookies->has('ECINSTALLER_TRANSACTION')) { + throw new AccessDeniedHttpException('Transaction token not found'); + } + $jws = $this->unserializeToken($request->cookies->get('ECINSTALLER_TRANSACTION')); $verifier = new JWSVerifier($this->getAlgorithmManager()); if ($verifier->verifyWithKey($jws, $this->getPublicJWK(), 0) === false) { throw new AccessDeniedHttpException('bad transaction signeture'); @@ -1178,7 +1185,7 @@ protected function isInstallEnv() private function getJwksDir() { $projectDir = $this->getParameter('kernel.project_dir'); - return $projectDir.'/var/cache/install/jwks'; + return $projectDir.'/var/jwks'; } /** @@ -1188,8 +1195,8 @@ private function createJwks() { $jwksDir = $this->getJwksDir(); if (!file_exists($jwksDir.'/'.self::JWK_PRIVATE) && !file_exists($jwksDir.'/'.self::JWK_PUBLIC)) { - if (!file_exists($this->jwksDir)) { - mkdir($this->jwksDir, 0755, true); + if (!file_exists($jwksDir)) { + mkdir($jwksDir, 0755, true); } $jwk = JWKFactory::createRSAKey(