These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php namespace Comodojo\Cookies; |
|||||||||||
2 | ||||||||||||
3 | use \Comodojo\Cookies\CookieInterface\CookieInterface; |
|||||||||||
4 | use \Comodojo\Exception\CookieException; |
|||||||||||
5 | use \Comodojo\Cookies\CookieBase; |
|||||||||||
6 | use \Crypt_AES; |
|||||||||||
7 | ||||||||||||
8 | /** |
|||||||||||
9 | * AES-encrypted cookie |
|||||||||||
10 | * |
|||||||||||
11 | * @package Comodojo Spare Parts |
|||||||||||
12 | * @author Marco Giovinazzi <[email protected]> |
|||||||||||
13 | * @license MIT |
|||||||||||
14 | * |
|||||||||||
15 | * LICENSE: |
|||||||||||
16 | * |
|||||||||||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||||||||||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||||||||||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||||||||||
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||||||||||
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||||||||||
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||||||||||
23 | * THE SOFTWARE. |
|||||||||||
24 | */ |
|||||||||||
25 | ||||||||||||
26 | class EncryptedCookie extends CookieBase implements CookieInterface { |
|||||||||||
27 | ||||||||||||
28 | /* |
|||||||||||
29 | * AES key |
|||||||||||
30 | * |
|||||||||||
31 | * @var int |
|||||||||||
32 | */ |
|||||||||||
33 | private $key = null; |
|||||||||||
34 | ||||||||||||
35 | /** |
|||||||||||
36 | * Encrypted cookie constructor |
|||||||||||
37 | * |
|||||||||||
38 | * Setup cookie name and key |
|||||||||||
39 | * |
|||||||||||
40 | * @param string $name |
|||||||||||
41 | * |
|||||||||||
42 | * @param string $key |
|||||||||||
43 | * |
|||||||||||
44 | * @throws \Comodojo\Exception\CookieException |
|||||||||||
45 | */ |
|||||||||||
46 | 21 | View Code Duplication | public function __construct($name, $key) { |
|||||||||
0 ignored issues
–
show
|
||||||||||||
47 | ||||||||||||
48 | 21 | if ( empty($key) OR !is_scalar($key) ) throw new CookieException("Invalid secret key"); |
||||||||||
49 | ||||||||||||
50 | 21 | $this->key = $key; |
||||||||||
51 | ||||||||||||
52 | try { |
|||||||||||
53 | ||||||||||||
54 | 21 | $this->setName($name); |
||||||||||
55 | ||||||||||||
56 | 7 | } catch (CookieException $ce) { |
||||||||||
57 | ||||||||||||
58 | throw $ce; |
|||||||||||
59 | ||||||||||||
60 | } |
|||||||||||
61 | ||||||||||||
62 | 21 | if ( defined("COMODOJO_COOKIE_MAX_SIZE") ) { |
||||||||||
63 | ||||||||||||
64 | $this->max_cookie_size = filter_var(COMODOJO_COOKIE_MAX_SIZE, FILTER_VALIDATE_INT, array( |
|||||||||||
65 | 'options' => array( |
|||||||||||
66 | 'default' => 4000 |
|||||||||||
67 | ) |
|||||||||||
68 | )); |
|||||||||||
69 | ||||||||||||
70 | } |
|||||||||||
71 | ||||||||||||
72 | 21 | } |
||||||||||
73 | ||||||||||||
74 | /** |
|||||||||||
75 | * Set cookie content |
|||||||||||
76 | * |
|||||||||||
77 | * @param mixed $value Cookie content |
|||||||||||
78 | * @param bool $serialize If true (default) cookie will be serialized first |
|||||||||||
79 | * |
|||||||||||
80 | * @return \Comodojo\Cookies\EncryptedCookie |
|||||||||||
81 | * |
|||||||||||
82 | * @throws \Comodojo\Exception\CookieException |
|||||||||||
83 | */ |
|||||||||||
84 | 12 | View Code Duplication | public function setValue($value, $serialize = true) { |
|||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
||||||||||||
85 | ||||||||||||
86 | 12 | if ( !is_scalar($value) AND $serialize === false ) throw new CookieException("Cannot set non-scalar value without serialization"); |
||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
87 | ||||||||||||
88 | 12 | if ( $serialize === true ) $value = serialize($value); |
||||||||||
89 | ||||||||||||
90 | 12 | $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB); |
||||||||||
91 | ||||||||||||
92 | 4 | $cipher->setKeyLength(256); |
||||||||||
93 | ||||||||||||
94 | 4 | $cipher->setKey(self::EncryptedKey($this->key)); |
||||||||||
95 | ||||||||||||
96 | // added base64 encoding to avoid problems with binary data |
|||||||||||
97 | ||||||||||||
98 | 4 | $encrypted_value = $cipher->encrypt($value); |
||||||||||
99 | ||||||||||||
100 | 4 | $cookie_value = base64_encode($encrypted_value); |
||||||||||
101 | ||||||||||||
102 | 4 | if ( strlen($cookie_value) > $this->max_cookie_size ) throw new CookieException("Cookie size larger than 4KB"); |
||||||||||
103 | ||||||||||||
104 | 3 | $this->value = $cookie_value; |
||||||||||
105 | ||||||||||||
106 | 3 | return $this; |
||||||||||
107 | ||||||||||||
108 | } |
|||||||||||
109 | ||||||||||||
110 | /** |
|||||||||||
111 | * Get cookie content |
|||||||||||
112 | * |
|||||||||||
113 | * @param bool $unserialize If true (default) cookie will be unserialized first |
|||||||||||
114 | * |
|||||||||||
115 | * @return mixed |
|||||||||||
116 | */ |
|||||||||||
117 | 3 | View Code Duplication | public function getValue($unserialize = true) { |
|||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
||||||||||||
118 | ||||||||||||
119 | 3 | $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB); |
||||||||||
120 | ||||||||||||
121 | 3 | $cipher->setKeyLength(256); |
||||||||||
122 | ||||||||||||
123 | 3 | $cipher->setKey(self::EncryptedKey($this->key)); |
||||||||||
124 | ||||||||||||
125 | // added base64 encoding to avoid problems with binary data |
|||||||||||
126 | ||||||||||||
127 | 3 | $encoded_cookie = base64_decode($this->value); |
||||||||||
128 | ||||||||||||
129 | 3 | if ( $encoded_cookie === false ) throw new CookieException("Cookie data cannot be decoded"); |
||||||||||
130 | ||||||||||||
131 | 3 | $cookie = $cipher->decrypt($encoded_cookie); |
||||||||||
132 | ||||||||||||
133 | 3 | if ( $cookie === false ) throw new CookieException("Cookie data cannot be dectypted"); |
||||||||||
134 | ||||||||||||
135 | 3 | return ($unserialize === true) ? unserialize($cookie) : $cookie; |
||||||||||
136 | ||||||||||||
137 | } |
|||||||||||
138 | ||||||||||||
139 | /** |
|||||||||||
140 | * Static method to create a cookie quickly |
|||||||||||
141 | * |
|||||||||||
142 | * @param string $name The cookie name |
|||||||||||
143 | * |
|||||||||||
144 | * @param string $key |
|||||||||||
145 | * |
|||||||||||
146 | * @param array $properties Array of properties cookie should have |
|||||||||||
147 | * |
|||||||||||
148 | * @return \Comodojo\Cookies\EncryptedCookie |
|||||||||||
149 | * |
|||||||||||
150 | * @throws \Comodojo\Exception\CookieException |
|||||||||||
151 | */ |
|||||||||||
152 | 3 | View Code Duplication | public static function create($name, $key, $properties = array(), $serialize = true) { |
|||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
||||||||||||
153 | ||||||||||||
154 | try { |
|||||||||||
155 | ||||||||||||
156 | 3 | $cookie = new EncryptedCookie($name, $key); |
||||||||||
157 | ||||||||||||
158 | 3 | self::cookieProperties($cookie, $properties, $serialize); |
||||||||||
159 | ||||||||||||
160 | 1 | } catch (CookieException $ce) { |
||||||||||
161 | ||||||||||||
162 | throw $ce; |
|||||||||||
163 | ||||||||||||
164 | } |
|||||||||||
165 | ||||||||||||
166 | 3 | return $cookie; |
||||||||||
167 | ||||||||||||
168 | } |
|||||||||||
169 | ||||||||||||
170 | /** |
|||||||||||
171 | * Static method to get a cookie quickly |
|||||||||||
172 | * |
|||||||||||
173 | * @param string $name The cookie name |
|||||||||||
174 | * |
|||||||||||
175 | * @param string $key |
|||||||||||
176 | * |
|||||||||||
177 | * @return \Comodojo\Cookies\EncryptedCookie |
|||||||||||
178 | * |
|||||||||||
179 | * @throws \Comodojo\Exception\CookieException |
|||||||||||
180 | */ |
|||||||||||
181 | 3 | View Code Duplication | public static function retrieve($name, $key) { |
|||||||||
182 | ||||||||||||
183 | try { |
|||||||||||
184 | ||||||||||||
185 | 3 | $cookie = new EncryptedCookie($name, $key); |
||||||||||
186 | ||||||||||||
187 | 3 | $return = $cookie->load(); |
||||||||||
188 | ||||||||||||
189 | 3 | } catch (CookieException $ce) { |
||||||||||
190 | ||||||||||||
191 | 3 | throw $ce; |
||||||||||
192 | ||||||||||||
193 | } |
|||||||||||
194 | ||||||||||||
195 | return $return; |
|||||||||||
196 | ||||||||||||
197 | } |
|||||||||||
198 | ||||||||||||
199 | /** |
|||||||||||
200 | * Create a client-specific key using provided key, |
|||||||||||
201 | * the client remote address and (in case) the value of |
|||||||||||
202 | * HTTP_X_FORWARDED_FOR header |
|||||||||||
203 | * |
|||||||||||
204 | * @param string $key |
|||||||||||
205 | * |
|||||||||||
206 | * @return string |
|||||||||||
207 | */ |
|||||||||||
208 | 4 | private static function EncryptedKey($key) { |
||||||||||
209 | ||||||||||||
210 | 4 | return hash('sha256', $key); |
||||||||||
211 | ||||||||||||
212 | } |
|||||||||||
213 | ||||||||||||
214 | } |
|||||||||||
215 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.