Browse Source

Check cipher names when encrypting or decrypting values.

mark_story 11 years ago
parent
commit
006b96b549

+ 32 - 7
src/Controller/Component/CookieComponent.php

@@ -100,6 +100,13 @@ class CookieComponent extends Component {
 	protected $_request;
 	protected $_request;
 
 
 /**
 /**
+ * Valid cipher names for encrypted cookies.
+ *
+ * @var array
+ */
+	protected $_validCiphers = ['aes', 'rijndael'];
+
+/**
  * Constructor
  * Constructor
  *
  *
  * @param ComponentRegistry $collection A ComponentRegistry for this component
  * @param ComponentRegistry $collection A ComponentRegistry for this component
@@ -327,6 +334,7 @@ class CookieComponent extends Component {
 		if (!$encrypt) {
 		if (!$encrypt) {
 			return $value;
 			return $value;
 		}
 		}
+		$this->_checkCipher($encrypt);
 		$prefix = "Q2FrZQ==.";
 		$prefix = "Q2FrZQ==.";
 		if ($encrypt === 'rijndael') {
 		if ($encrypt === 'rijndael') {
 			$cipher = Security::rijndael($value, $this->_config['key'], 'encrypt');
 			$cipher = Security::rijndael($value, $this->_config['key'], 'encrypt');
@@ -338,6 +346,23 @@ class CookieComponent extends Component {
 	}
 	}
 
 
 /**
 /**
+ * Helper method for validating encryption cipher names.
+ *
+ * @param string $encrypt The cipher name.
+ * @return void
+ * @throws \RuntimeException When an invalid cipher is provided.
+ */
+	protected function _checkCipher($encrypt) {
+		if (!in_array($encrypt, $this->_validCiphers)) {
+			$msg = sprintf(
+				'Invalid encryption cipher. Must be one of %s.',
+				implode(', ', $this->_validCiphers)
+			);
+			throw new \RuntimeException($msg);
+		}
+	}
+
+/**
  * Decrypts $value using public $type method in Security class
  * Decrypts $value using public $type method in Security class
  *
  *
  * @param array $values Values to decrypt
  * @param array $values Values to decrypt
@@ -366,20 +391,20 @@ class CookieComponent extends Component {
  * Decodes and decrypts a single value.
  * Decodes and decrypts a single value.
  *
  *
  * @param string $value The value to decode & decrypt.
  * @param string $value The value to decode & decrypt.
- * @param string|false $encryption The encryption cipher to use.
+ * @param string|false $encrypt The encryption cipher to use.
  * @return string Decoded value.
  * @return string Decoded value.
  */
  */
-	protected function _decode($value, $encryption) {
-		$prefix = 'Q2FrZQ==.';
-		$pos = strpos($value, $prefix);
-		if (!$encryption) {
+	protected function _decode($value, $encrypt) {
+		if (!$encrypt) {
 			return $this->_explode($value);
 			return $this->_explode($value);
 		}
 		}
+		$this->_checkCipher($encrypt);
+		$prefix = 'Q2FrZQ==.';
 		$value = base64_decode(substr($value, strlen($prefix)));
 		$value = base64_decode(substr($value, strlen($prefix)));
-		if ($encryption === 'rijndael') {
+		if ($encrypt === 'rijndael') {
 			$value = Security::rijndael($value, $this->_config['key'], 'decrypt');
 			$value = Security::rijndael($value, $this->_config['key'], 'decrypt');
 		}
 		}
-		if ($encryption === 'aes') {
+		if ($encrypt === 'aes') {
 			$value = Security::decrypt($value, $this->_config['key']);
 			$value = Security::decrypt($value, $this->_config['key']);
 		}
 		}
 		return $this->_explode($value);
 		return $this->_explode($value);

+ 27 - 0
tests/TestCase/Controller/Component/CookieComponentTest.php

@@ -132,6 +132,21 @@ class CookieComponentTest extends TestCase {
 	}
 	}
 
 
 /**
 /**
+ * Test read when an invalid cipher is configured.
+ *
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage Invalid encryption cipher. Must be one of aes, rijndael.
+ * @return void
+ */
+	public function testReadInvalidCipher() {
+		$this->request->cookies = [
+			'Test' => $this->_encrypt('value'),
+		];
+		$this->Cookie->config('encryption', 'derp');
+		$this->Cookie->read('Test');
+	}
+
+/**
  * testReadEncryptedCookieData
  * testReadEncryptedCookieData
  *
  *
  * @return void
  * @return void
@@ -195,6 +210,18 @@ class CookieComponentTest extends TestCase {
 	}
 	}
 
 
 /**
 /**
+ * Test write when an invalid cipher is configured.
+ *
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage Invalid encryption cipher. Must be one of aes, rijndael.
+ * @return void
+ */
+	public function testWriteInvalidCipher() {
+		$this->Cookie->config('encryption', 'derp');
+		$this->Cookie->write('Test', 'nope');
+	}
+
+/**
  * Test writes don't omit request data from being read.
  * Test writes don't omit request data from being read.
  *
  *
  * @return void
  * @return void