Issues (1131)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/request/WebRequestDataHolder.class.php (8 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Agavi\Request;
3
4
// +---------------------------------------------------------------------------+
5
// | This file is part of the Agavi package.                                   |
6
// | Copyright (c) 2005-2011 the Agavi Project.                                |
7
// |                                                                           |
8
// | For the full copyright and license information, please view the LICENSE   |
9
// | file that was distributed with this source code. You can also view the    |
10
// | LICENSE file online at http://www.agavi.org/LICENSE.txt                   |
11
// |   vi: set noexpandtab:                                                    |
12
// |   Local Variables:                                                        |
13
// |   indent-tabs-mode: t                                                     |
14
// |   End:                                                                    |
15
// +---------------------------------------------------------------------------+
16
use Agavi\Util\ArrayPathDefinition;
17
18
/**
19
 * AgaviWebRequestDataHolder provides methods for retrieving client request
20
 * information parameters.
21
 *
22
 * @package    agavi
23
 * @subpackage request
24
 *
25
 * @author     Dominik del Bondio <[email protected]>
26
 * @author     David Zülke <[email protected]>
27
 * @copyright  Authors
28
 * @copyright  The Agavi Project
29
 *
30
 * @since      0.11.0
31
 *
32
 * @version    $Id$
33
 */
34
class WebRequestDataHolder extends RequestDataHolder implements CookiesRequestDataHolderInterface, FilesRequestDataHolderInterface, HeadersRequestDataHolderInterface
35
{
36
    /**
37
     * @constant   Constant for source name of cookies.
38
     */
39
    const SOURCE_COOKIES = 'cookies';
40
    
41
    /**
42
     * @constant   Constant for source name of files.
43
     */
44
    const SOURCE_FILES = 'files';
45
    
46
    /**
47
     * @constant   Constant for source name of HTTP headers.
48
     */
49
    const SOURCE_HEADERS = 'headers';
50
    
51
    /**
52
     * @var        array An (proper) array of files uploaded during the request.
53
     */
54
    protected $files = array();
55
    
56
    /**
57
     * @var        array An array of cookies set in the request.
58
     */
59
    protected $cookies = array();
60
    
61
    /**
62
     * @var        array An array of headers sent with the request.
63
     */
64
    protected $headers = array();
65
66
    /**
67
     * Checks if there is a value of a parameter is empty or not set.
68
     *
69
     * @param      string $field The field name.
70
     *
71
     * @return     bool The result.
72
     *
73
     * @author     David Zülke <[email protected]>
74
     * @author     Dominik del Bondio <[email protected]>
75
     * @since      0.11.0
76
     */
77
    public function isParameterValueEmpty($field)
78
    {
79
        $value = $this->getParameter($field);
80
        return ($value === null || $value === '');
81
    }
82
83
    /**
84
     * Clear all cookies.
85
     *
86
     * @author     Dominik del Bondio <[email protected]>
87
     * @since      0.11.0
88
     */
89
    public function clearCookies()
90
    {
91
        $this->cookies = array();
92
    }
93
94
    /**
95
     * Indicates whether or not a Cookie exists.
96
     *
97
     * @param      string $name A cookie name.
98
     *
99
     * @return     bool True, if a cookie with that name exists, otherwise false.
100
     *
101
     * @author     David Zülke <[email protected]>
102
     * @since      0.11.0
103
     */
104 View Code Duplication
    public function hasCookie($name)
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...
105
    {
106
        if (isset($this->cookies[$name]) || array_key_exists($name, $this->cookies)) {
107
            return true;
108
        }
109
        try {
110
            return ArrayPathDefinition::hasValue($name, $this->cookies);
111
        } catch (\InvalidArgumentException $e) {
112
            return false;
113
        }
114
    }
115
116
    /**
117
     * Checks if there is a value of a cookie is empty or not set.
118
     *
119
     * @param      string $name The cookie name.
120
     *
121
     * @return     bool The result.
122
     *
123
     * @author     David Zülke <[email protected]>
124
     * @author     Dominik del Bondio <[email protected]>
125
     * @since      0.11.0
126
     */
127
    public function isCookieValueEmpty($name)
128
    {
129
        return ($this->getCookie($name) === null);
130
    }
131
132
    /**
133
     * Retrieve a value stored into a cookie.
134
     *
135
     * @param      string $name A cookie name.
136
     * @param      mixed  $default A default value.
137
     *
138
     * @return     mixed The value from the cookie, if such a cookie exists,
139
     *                   otherwise null.
140
     *
141
     * @author     Veikko Mäkinen <[email protected]>
142
     * @author     David Zülke <[email protected]>
143
     * @since      0.11.0
144
     */
145 View Code Duplication
    public function &getCookie($name, $default = null)
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...
146
    {
147
        if (isset($this->cookies[$name]) || array_key_exists($name, $this->cookies)) {
148
            return $this->cookies[$name];
149
        }
150
        try {
151
            return ArrayPathDefinition::getValue($name, $this->cookies, $default);
152
        } catch (\InvalidArgumentException $e) {
153
            return $default;
154
        }
155
    }
156
157
    /**
158
     * Set a cookie.
159
     *
160
     * If a cookie with the name already exists the value will be overridden.
161
     *
162
     * @param      string $name A cookie name.
163
     * @param      mixed  $value A cookie value.
164
     *
165
     * @author     Dominik del Bondio <[email protected]>
166
     * @since      0.11.0
167
     */
168
    public function setCookie($name, $value)
169
    {
170
        $this->cookies[$name] = $value;
171
    }
172
173
    /**
174
     * Set an array of cookies.
175
     *
176
     * If an existing cookie name matches any of the keys in the supplied
177
     * array, the associated value will be overridden.
178
     *
179
     * @param      array $cookies An associative array of cookies and their values.
180
     *
181
     * @author     Dominik del Bondio <[email protected]>
182
     * @since      0.11.0
183
     */
184
    public function setCookies(array $cookies)
185
    {
186
        $this->cookies = array_merge($this->cookies, $cookies);
187
    }
188
189
    /**
190
     * Remove a cookie.
191
     *
192
     * @param      string $name The cookie name
193
     *
194
     * @return     string The value of the removed cookie, if it had been set.
195
     *
196
     * @author     David Zülke <[email protected]>
197
     * @author     Dominik del Bondio <[email protected]>
198
     * @since      0.11.0
199
     */
200 View Code Duplication
    public function &removeCookie($name)
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...
201
    {
202
        if (isset($this->cookies[$name]) || array_key_exists($name, $this->cookies)) {
203
            $retval =& $this->cookies[$name];
204
            unset($this->cookies[$name]);
205
            return $retval;
206
        }
207
        try {
208
            return ArrayPathDefinition::unsetValue($name, $this->cookies);
209
        } catch (\InvalidArgumentException $e) {
210
            return null;
211
        }
212
    }
213
214
    /**
215
     * Retrieve all cookies.
216
     *
217
     * @return     array The cookies.
218
     *
219
     * @author     Dominik del Bondio <[email protected]>
220
     * @since      0.11.0
221
     */
222
    public function &getCookies()
223
    {
224
        return $this->cookies;
225
    }
226
227
    /**
228
     * Retrieve an array of cookie names.
229
     *
230
     * @return     array An indexed array of cookie names.
231
     *
232
     * @author     David Zülke <[email protected]>
233
     * @since      0.11.0
234
     */
235
    public function getCookieNames()
236
    {
237
        return array_keys($this->cookies);
238
    }
239
    
240
    /**
241
     * Retrieve an array of flattened cookie names. This means when a cookie is an
242
     * array you wont get the name of the cookie in the result but instead all
243
     * child keys appended to the name (like foo[0],foo[1][0], ...).
244
     *
245
     * @return     array An indexed array of cookie names.
246
     *
247
     * @author     David Zülke <[email protected]>
248
     * @since      0.11.0
249
     */
250
    public function getFlatCookieNames()
251
    {
252
        return ArrayPathDefinition::getFlatKeyNames($this->cookies);
253
    }
254
    
255
    /**
256
     * Clear all headers.
257
     *
258
     * @author     Dominik del Bondio <[email protected]>
259
     * @since      0.11.0
260
     */
261
    public function clearHeaders()
262
    {
263
        $this->headers = array();
264
    }
265
266
    /**
267
     * Retrieve all HTTP headers.
268
     *
269
     * @return     array A list of HTTP headers (keys in original PHP format).
270
     *
271
     * @author     David Zülke <[email protected]>
272
     * @since      0.11.0
273
     */
274
    public function &getHeaders()
275
    {
276
        return $this->headers;
277
    }
278
    
279
    /**
280
     * Get a HTTP header.
281
     *
282
     * @param      string $name Case-insensitive name of a header, using either a hyphen
283
     *                    or an underscore as a separator.
284
     * @param      mixed  $default A default value.
285
     *
286
     * @return     string The header value, or null if header wasn't set.
287
     *
288
     * @author     David Zülke <[email protected]>
289
     * @since      0.11.0
290
     */
291
    public function &getHeader($name, $default = null)
292
    {
293
        $name = str_replace('-', '_', strtoupper($name));
294
        if (isset($this->headers[$name]) || array_key_exists($name, $this->headers)) {
295
            return $this->headers[$name];
296
        }
297
298
        return $default;
299
    }
300
    
301
    /**
302
     * Check if a HTTP header exists.
303
     *
304
     * @param      string $name Case-insensitive name of a header, using either a hyphen
305
     *                    or an underscore as a separator.
306
     *
307
     * @return     bool True if the header was sent with the current request.
308
     *
309
     * @author     David Zülke <[email protected]>
310
     * @since      0.11.0
311
     */
312
    public function hasHeader($name)
313
    {
314
        $name = str_replace('-', '_', strtoupper($name));
315
        return (isset($this->headers[$name]) || array_key_exists($name, $this->headers));
316
    }
317
    
318
    /**
319
     * Checks if there is a value of a header is empty or not set.
320
     *
321
     * @param      string $name The header name.
322
     *
323
     * @return     bool The result.
324
     *
325
     * @author     David Zülke <[email protected]>
326
     * @author     Dominik del Bondio <[email protected]>
327
     * @since      0.11.0
328
     */
329
    public function isHeaderValueEmpty($name)
330
    {
331
        return ($this->getHeader($name) === null);
332
    }
333
    /**
334
     * Set a header.
335
     *
336
     * The header name is normalized before storing it.
337
     *
338
     * @param      string $name A header name.
339
     * @param      mixed  $value A header value.
340
     *
341
     * @author     David Zülke <[email protected]>
342
     * @author     Dominik del Bondio <[email protected]>
343
     * @since      0.11.0
344
     */
345
    public function setHeader($name, $value)
346
    {
347
        $this->headers[str_replace('-', '_', strtoupper($name))] = $value;
348
    }
349
350
    /**
351
     * Set an array of headers.
352
     *
353
     * @param      array $headers An associative array of headers and their values.
354
     *
355
     * @author     Dominik del Bondio <[email protected]>
356
     * @since      0.11.0
357
     */
358
    public function setHeaders(array $headers)
359
    {
360
        $this->headers = array_merge($this->headers, $headers);
361
    }
362
363
    /**
364
     * Remove a HTTP header.
365
     *
366
     * @param      string $name Case-insensitive name of a header, using either a hyphen
367
     *                    or an underscore as a separator.
368
     *
369
     * @return     string The value of the removed header, if it had been set.
370
     *
371
     * @author     David Zülke <[email protected]>
372
     * @since      0.11.0
373
     */
374
    public function &removeHeader($name)
375
    {
376
        $retval = null;
377
        $name = str_replace('-', '_', strtoupper($name));
378 View Code Duplication
        if (isset($this->headers[$name]) || array_key_exists($name, $this->headers)) {
0 ignored issues
show
This code seems to be duplicated across 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...
379
            $retval =& $this->headers[$name];
380
            unset($this->headers[$name]);
381
        }
382
        return $retval;
383
    }
384
    
385
    /**
386
     * Retrieve an array of header names.
387
     *
388
     * @return     array An indexed array of header names in original PHP format.
389
     *
390
     * @author     David Zülke <[email protected]>
391
     * @since      0.11.0
392
     */
393
    public function getHeaderNames()
394
    {
395
        return array_keys($this->headers);
396
    }
397
    
398
    /**
399
     * Retrieve an array of file information.
400
     *
401
     * @param      string $name A file name.
402
     * @param      mixed  $default A default return value.
403
     *
404
     * @return     mixed An AgaviUploadedFile object with file information, or an
405
     *                   array if the field name has child elements, or null (or
406
     *                   the supplied default return value) no such file exists.
407
     *
408
     * @author     David Zülke <[email protected]>
409
     * @since      0.11.0
410
     */
411 View Code Duplication
    public function &getFile($name, $default = null)
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...
412
    {
413
        if ((isset($this->files[$name]) || array_key_exists($name, $this->files))) {
414
            $retval =& $this->files[$name];
415
        } else {
416
            try {
417
                $retval =& ArrayPathDefinition::getValue($name, $this->files);
418
            } catch (\InvalidArgumentException $e) {
419
                $retval = $default;
420
            }
421
        }
422
        if (is_array($retval) || $retval instanceof UploadedFile) {
423
            return $retval;
424
        }
425
        return $default;
426
    }
427
428
    /**
429
     * Retrieve an array of files.
430
     *
431
     * @return     array An associative array of files.
432
     *
433
     * @author     David Zülke <[email protected]>
434
     * @since      0.11.0
435
     */
436
    public function &getFiles()
437
    {
438
        return $this->files;
439
    }
440
441
    /**
442
     * Indicates whether or not a file exists.
443
     *
444
     * @param      string $name A file name.
445
     *
446
     * @return     bool true, if the file exists, otherwise false.
447
     *
448
     * @author     David Zülke <[email protected]>
449
     * @since      0.11.0
450
     */
451 View Code Duplication
    public function hasFile($name)
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...
452
    {
453
        if ((isset($this->files[$name]) || array_key_exists($name, $this->files))) {
454
            $val = $this->files[$name];
455
        } else {
456
            try {
457
                $val = ArrayPathDefinition::getValue($name, $this->files);
458
            } catch (\InvalidArgumentException $e) {
459
                return false;
460
            }
461
        }
462
        return (is_array($val) || $val instanceof UploadedFile);
463
    }
464
465
    /**
466
     * Indicates whether or not any files exist.
467
     *
468
     * @return     bool true, if any files exist, otherwise false.
469
     *
470
     * @author     David Zülke <[email protected]>
471
     * @author     Sean Kerr <[email protected]>
472
     * @since      0.11.0
473
     */
474
    public function hasFiles()
475
    {
476
        return count($this->files) > 0;
477
    }
478
479
    /**
480
     * Checks if a file is empty, i.e. not set or set, but not actually uploaded.
481
     *
482
     * @param      string $name The file name.
483
     *
484
     * @return     bool The result.
485
     *
486
     * @author     David Zülke <[email protected]>
487
     * @author     Dominik del Bondio <[email protected]>
488
     * @since      0.11.0
489
     */
490 View Code Duplication
    public function isFileValueEmpty($name)
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...
491
    {
492
        $file = $this->getFile($name);
493
        if (!($file instanceof UploadedFile)) {
494
            return true;
495
        }
496
        return ($file->getError() == UPLOAD_ERR_NO_FILE);
497
    }
498
499
    /**
500
     * Removes file information for given file.
501
     *
502
     * @param      string $name A file name
503
     *
504
     * @return     mixed The old UploadedFile instance or array of elements.
505
     *
506
     * @author     David Zülke <[email protected]>
507
     * @author     Dominik del Bondio <[email protected]>
508
     * @since      0.11.0
509
     */
510 View Code Duplication
    public function &removeFile($name)
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...
511
    {
512
        if (isset($this->files[$name]) || array_key_exists($name, $this->files)) {
513
            $retval =& $this->files[$name];
514
            unset($this->files[$name]);
515
            return $retval;
516
        }
517
        try {
518
            return ArrayPathDefinition::unsetValue($name, $this->files);
519
        } catch (\InvalidArgumentException $e) {
520
            return null;
521
        }
522
    }
523
524
    /**
525
     * Set a file.
526
     *
527
     * If a file with the name already exists the value will be overridden.
528
     *
529
     * @param      string       $name A file name.
530
     * @param      UploadedFile $file An UploadedFile object.
531
     *
532
     * @author     David Zülke <[email protected]>
533
     * @since      0.11.0
534
     */
535
    public function setFile($name, UploadedFile $file)
536
    {
537
        $this->files[$name] = $file;
538
    }
539
540
    /**
541
     * Set an array of files.
542
     *
543
     * @param      array $files An assoc array of names and AgaviUploadedFile objects.
544
     *
545
     * @author     Dominik del Bondio <[email protected]>
546
     * @since      0.11.0
547
     */
548
    public function setFiles(array $files)
549
    {
550
        $this->files = array_merge($this->files, $files);
551
    }
552
553
    /**
554
     * Clear all files.
555
     *
556
     * @author     Dominik del Bondio <[email protected]>
557
     * @since      0.11.0
558
     */
559
    public function clearFiles()
560
    {
561
        $this->files = array();
562
    }
563
564
    /**
565
     * Retrieve an array of file names.
566
     *
567
     * @return     array An indexed array of file names.
568
     *
569
     * @author     David Zülke <[email protected]>
570
     * @since      0.11.0
571
     */
572
    public function getFileNames()
573
    {
574
        return array_keys($this->files);
575
    }
576
    
577
    /**
578
     * Retrieve an array of flattened file names. This means when a file is an
579
     * array you wont get the name of the file in the result but instead all child
580
     * keys appended to the name (like foo[0],foo[1][0], ...).
581
     *
582
     * @return     array An indexed array of file names.
583
     *
584
     * @author     David Zülke <[email protected]>
585
     * @since      0.11.0
586
     */
587
    public function getFlatFileNames()
588
    {
589
        return ArrayPathDefinition::getFlatKeyNames($this->files);
590
    }
591
    
592
    /**
593
     * Constructor
594
     *
595
     * @param      array $data An associative array of request data source names and
596
     *                   data arrays.
597
     *
598
     * @author     David Zülke <[email protected]>
599
     * @since      0.11.0
600
     */
601
    public function __construct(array $data = array())
602
    {
603
        $this->registerSource(self::SOURCE_COOKIES, $this->cookies);
604
        $this->registerSource(self::SOURCE_FILES, $this->files);
605
        $this->registerSource(self::SOURCE_HEADERS, $this->headers);
606
        
607
        // call the parent ctor which handles the actual loading of the data
608
        parent::__construct($data);
609
    }
610
    
611
    /**
612
     * Merge in Cookies from another request data holder.
613
     *
614
     * @param      RequestDataHolder $other The other request data holder.
615
     *
616
     * @author     David Zülke <[email protected]>
617
     * @since      0.11.0
618
     */
619
    public function mergeCookies(RequestDataHolder $other)
620
    {
621
        if ($other instanceof CookiesRequestDataHolderInterface) {
622
            $this->setCookies($other->getCookies());
623
        }
624
    }
625
    
626
    /**
627
     * Merge in Files from another request data holder.
628
     *
629
     * @param      RequestDataHolder $other The other request data holder.
630
     *
631
     * @author     David Zülke <[email protected]>
632
     * @since      0.11.0
633
     */
634
    public function mergeFiles(RequestDataHolder $other)
635
    {
636
        if ($other instanceof FilesRequestDataHolderInterface) {
637
            $this->setFiles($other->getFiles());
638
        }
639
    }
640
    
641
    /**
642
     * Merge in Headers from another request data holder.
643
     *
644
     * @param      RequestDataHolder $other The other request data holder.
645
     *
646
     * @author     David Zülke <[email protected]>
647
     * @since      0.11.0
648
     */
649
    public function mergeHeaders(RequestDataHolder $other)
650
    {
651
        if ($other instanceof HeadersRequestDataHolderInterface) {
652
            $this->setHeaders($other->getHeaders());
653
        }
654
    }
655
}
656