Issues (42)

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/Psr/Messages/Request.php (11 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
3
namespace Almendra\Http\Psr\Messages;
4
5
use Psr\Http\Message\RequestInterface;
6
use Psr\Http\Message\UriInterface;
7
use Almendra\Http\Psr\Messages\Environment;
8
9
use Almendra\Http\Server;
10
11
/**
12
 * Represents an incomming request.
13
 * Server specific methods are left to ServerRequest.
14
 *
15
 * @package Almendra\Http
16
 * @author 	author 	<email>
17
 */
18
class Request extends Message implements RequestInterface
19
{
20
    protected $_target;
21
    protected $_method;
22
    protected $_Uri;
23
    protected $_params = [];
24
25
    protected $_contentType;
26
27
    protected $_scriptName;
28
    protected $_queryString;
29
    protected $_serverName;
30
    protected $_serverPort;
31
    protected $_host;
32
    protected $_accept;
33
    protected $_acceptLanguage;
34
    protected $_acceptCharset;
35
    protected $_userAgent;
36
    protected $_remoteAddr;
37
    protected $_time;
38
    protected $_timeFloat;
39
40
    protected $_fields = [];
41
42
    
43
    public function __construct(UriInterface $uri = null)
44
    {
45
        if (isset($uri) && $uri !== null) {
46
            $this -> setUri($uri);
47
        }
48
    }
49
50
    public function createFromEnvironment(Environment $environment)
51
    {
52
        $params = $environment::init([]);
53
54
        // repart values among the properties
55
        foreach ($params as $param => $value) {
56
            // $this -> _params[$param] = $value; // @tmp for debugging
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
57
            $this -> assign($param, $value);
58
        }
59
60
        $this -> fillFields($this -> getMethod());
61
62
        return $this;
63
    }
64
65
    /**
66
     * Assign the environmental values to the proper members
67
     *
68
     * @param string $key 			Environmental value key
69
     * @param string $value 		Environmental value value
70
     * @return boolean 				false if failure
71
     */
72
    public function assign($key, $value)
73
    {
74
        switch ($key) {
75
            case 'SCRIPT_NAME':
76
                $this -> _scriptName = $value;
77
                break;
78
79
            case 'REQUEST_METHOD':
80
                $this -> setMethod($value);
81
                break;
82
83
            case 'REQUEST_URI':
84
                $this -> setUri(new Uri($value));
85
                break;
86
87
            case 'SERVER_PROTOCOL':
88
                $this -> _protocolVersion = $value;
89
                break;
90
91
            case 'SCRIPT_NAME':
92
                $this -> _scriptName = $value;
93
                break;
94
95
            case 'QUERY_STRING':
96
                $this -> _queryString = $value;
97
                break;
98
99
            case 'SERVER_NAME':
100
                $this -> _serverName = $value;
101
                break;
102
103
            case 'SERVER_PORT':
104
                $this -> _serverPort = $value;
105
                break;
106
107
            case 'HTTP_HOST':
108
                $this -> _host = $value;
109
                break;
110
111
            case 'HTTP_ACCEPT':
112
                $this -> _accept = $value;
113
                break;
114
115
            case 'HTTP_ACCEPT_LANGUAGE':
116
                $this -> _acceptLanguage = $value;
117
                break;
118
119
            case 'HTTP_ACCEPT_CHARSET':
120
                $this -> _acceptCharset = $value;
121
                break;
122
123
            case 'HTTP_USER_AGENT':
124
                $this -> _userAgent = $value;
125
                break;
126
127
            case 'REMOTE_ADDR':
128
                $this -> _remoteAddr = $value;
129
                break;
130
131
            case 'REQUEST_TIME':
132
                $this -> _time = $value;
133
                break;
134
135
            case 'REQUEST_TIME_FLOAT':
136
                $this -> _timeFloat = $value;
137
                break;
138
139
            case 'CONTENT_TYPE':
140
                $this -> _contentType = $value;
141
                break;
142
143
            default:
144
                return false;
145
                break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
146
        }
147
148
        return true;
149
    }
150
151
    /**
152
     * Retrieves the message's request target.
153
     *
154
     * Retrieves the message's request-target either as it will appear (for
155
     * clients), as it appeared at request (for servers), or as it was
156
     * specified for the instance (see withRequestTarget()).
157
     *
158
     * In most cases, this will be the origin-form of the composed URI,
159
     * unless a value was provided to the concrete implementation (see
160
     * withRequestTarget() below).
161
     *
162
     * If no URI is available, and no request-target has been specifically
163
     * provided, this method MUST return the string "/".
164
     *
165
     * @return string
166
     */
167
    public function getRequestTarget()
168
    {
169
        // retrieve the target
170
        $target = ('' != $this -> getUri() -> getPath()) ?
171
            $this -> getUri() -> getPath() :
172
            '/';
173
174
        // attach the query parameters
175
        $params = $this -> getUri() -> getQuery();
176
        if ('' != $params) {
177
            $target .= '?' . $params;
178
        }
179
180
        return $target;
181
    }
182
183
    /**
184
     * Return an instance with the specific request-target.
185
     *
186
     * If the request needs a non-origin-form request-target — e.g., for
187
     * specifying an absolute-form, authority-form, or asterisk-form —
188
     * this method may be used to create an instance with the specified
189
     * request-target, verbatim.
190
     *
191
     * This method MUST be implemented in such a way as to retain the
192
     * immutability of the message, and MUST return an instance that has the
193
     * changed request target.
194
     *
195
     * @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
196
     *     request-target forms allowed in request messages)
197
     * @param mixed $requestTarget
0 ignored issues
show
There is no parameter named $requestTarget. Did you maybe mean $target?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
198
     * @return static
199
     */
200
    public function withRequestTarget($target)
201
    {
202
        $clone = clone $this;
203
        $clone -> setRequestTarget($target);
204
205
        return $clone;
206
    }
207
208
    /**
209
     * Sets the request-target.
210
     *
211
     * @param string $target         
212
     * @return void                 
213
     */
214
    public function setRequestTarget($target)
215
    {
216
        $this -> _target = $target;
217
    }
218
219
    /**
220
     * Retrieves the HTTP method of the request.
221
     *
222
     * @return string Returns the request method.
223
     */
224
    public function getMethod()
225
    {
226
        return $this -> _method;
227
    }
228
229
    /**
230
     * Overrides the request method.
231
     *
232
     * @param string $method         The HTTP method
233
     * @return void                 
234
     */
235
    public function setMethod($method)
236
    {
237
        $this -> _method = $method;
238
    }
239
240
    /**
241
     * Return an instance with the provided HTTP method.
242
     *
243
     * While HTTP method names are typically all uppercase characters, HTTP
244
     * method names are case-sensitive and thus implementations SHOULD NOT
245
     * modify the given string.
246
     *
247
     * This method MUST be implemented in such a way as to retain the
248
     * immutability of the message, and MUST return an instance that has the
249
     * changed request method.
250
     *
251
     * @param string $method Case-sensitive method.
252
     * @return static
253
     * @throws \InvalidArgumentException for invalid HTTP methods.
254
     */
255
    public function withMethod($method)
256
    {
257
        $clone = clone $this;
258
        $clone -> setMethod($method);
259
260
        return $clone;
261
    }
262
263
    /**
264
     * Retrieves the URI instance.
265
     *
266
     * This method MUST return a UriInterface instance.
267
     *
268
     * @link http://tools.ietf.org/html/rfc3986#section-4.3
269
     * @return UriInterface Returns a UriInterface instance
270
     *     representing the URI of the request.
271
     */
272
    public function getUri()
273
    {
274
        return $this -> _Uri;
275
    }
276
277
    /**
278
     * Sets the request URI.
279
     *
280
     * @param UriInterface $uri         The URI
281
     * @return void                 
282
     */
283
    public function setUri(UriInterface $uri)
284
    {
285
        $this -> _Uri = $uri;
286
    }
287
288
    /**
289
     * Returns an instance with the provided URI.
290
     *
291
     * This method MUST update the Host header of the returned request by
292
     * default if the URI contains a host component. If the URI does not
293
     * contain a host component, any pre-existing Host header MUST be carried
294
     * over to the returned request.
295
     *
296
     * You can opt-in to preserving the original state of the Host header by
297
     * setting `$preserveHost` to `true`. When `$preserveHost` is set to
298
     * `true`, this method interacts with the Host header in the following ways:
299
     *
300
     * - If the Host header is missing or empty, and the new URI contains
301
     *   a host component, this method MUST update the Host header in the returned
302
     *   request.
303
     * - If the Host header is missing or empty, and the new URI does not contain a
304
     *   host component, this method MUST NOT update the Host header in the returned
305
     *   request.
306
     * - If a Host header is present and non-empty, this method MUST NOT update
307
     *   the Host header in the returned request.
308
     *
309
     * This method MUST be implemented in such a way as to retain the
310
     * immutability of the message, and MUST return an instance that has the
311
     * new UriInterface instance.
312
     *
313
     * @link http://tools.ietf.org/html/rfc3986#section-4.3
314
     * @param UriInterface $uri New request URI to use.
315
     * @param bool $preserveHost Preserve the original state of the Host header.
316
     * @return static
317
     */
318
    public function withUri(UriInterface $uri, $preserveHost = false)
319
    {
320
        $clone = clone $this;
321
        $clone -> setUri($uri);
322
323
        return $clone;
324
    }
325
326
    /**
327
     * Returns all the request fields.
328
     *
329
     * @return mixed                 
330
     */
331
    public function all()
332
    {
333
        return $this -> _fields;
334
    }
335
336
    /**
337
     * Returns the request field by name corresponding the to GET method.
338
     * Null if none exists.
339
     *
340
     * @param string $name         The field's name
341
     * @return mixed                 
342
     */
343 View Code Duplication
    public function get($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...
344
    {
345
        if (isset($this -> _fields['get'][$name])) {
346
            return $this -> _fields['get'][$name];
347
        }
348
349
        return null;
350
    }
351
352
    /**
353
     * Returns the request field by name corresponding the to POST method.
354
     * Null if none exists.
355
     *
356
     * @param string $name         The field's name
357
     * @return mixed                 
358
     */
359 View Code Duplication
    public function post($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...
360
    {
361
        if (isset($this -> _fields['post'][$name])) {
362
            return $this -> _fields['post'][$name];
363
        }
364
365
        return null;
366
    }
367
368
    /**
369
     * Returns the request field by name corresponding the to PUT method.
370
     * Null if none exists.
371
     *
372
     * @param string $name         The field's name
373
     * @return mixed                 
374
     */
375 View Code Duplication
    public function put($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...
376
    {
377
        if (isset($this -> _fields['put'][$name])) {
378
            return $this -> _fields['put'][$name];
379
        }
380
381
        return null;
382
    }
383
384
    /**
385
     * Returns the request field by name corresponding the to DELETE method.
386
     * Null if none exists.
387
     *
388
     * @param string $name         The field's name
389
     * @return mixed                 
390
     */
391 View Code Duplication
    public function delete($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...
392
    {
393
        if (isset($this -> _fields['delete'][$name])) {
394
            return $this -> _fields['delete'][$name];
395
        }
396
397
        return null;
398
    }
399
400
    /**
401
     * Returns the request file field by name usually found thourgh the $_SERVER super-global. 
402
     * Null if none exists.
403
     *
404
     * @param string $name         The field's name
405
     * @return mixed                 
406
     */
407 View Code Duplication
    public function files($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...
408
    {
409
        if (isset($this -> _fields['files'][$name])) {
410
            return $this -> _fields['files'][$name];
411
        }
412
413
        return null;
414
    }
415
416
417
    protected function fillFields($method)
418
    {
419
        $server = new Server;
420
        $fields = [];
421
422
        $fields['files'] = $server -> files() -> all();
423
        switch ($method) {
424
            case 'GET':
425
                $fields['get'] = $server -> get() -> all();
0 ignored issues
show
The call to get() misses a required argument $name.

This check looks for function calls that miss required arguments.

Loading history...
426
                break;
427
428
            case 'POST':
429
                $fields['post'] = $server -> post() -> all();
0 ignored issues
show
The call to post() misses a required argument $name.

This check looks for function calls that miss required arguments.

Loading history...
430
                break;
431
432
            default:
433
                throw new \InvalidMethodException("No valid method provided.");
434
                break;
0 ignored issues
show
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
435
        }
436
437
        $this -> _fields = $fields;
438
    }
439
}
440