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/Uri.php (4 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\UriInterface;
6
7
use Almendra\Http\Helpers\URI as URIHelper;
8
use Almendra\Http\Server;
9
10
/**
11
 * Represents an URI.
12
 *
13
 * @package     Almendra\Psr7
14
 * @author      Richard Trujillo Torres     <[email protected]>
15
 */
16
class Uri implements UriInterface
17
{
18
    /**
19
     * @var string
20
     */
21
    protected $_uri;
22
23
    /**
24
     * @var string The URI's scheme
25
     */
26
    protected $_scheme = 'blob'; // User-Agent
27
28
    /**
29
     * @var string The URI's query
30
     */
31
    protected $_query;
32
33
    /**
34
     * @var string The URI's path
35
     */
36
    protected $_path;
37
38
    /**
39
     * @var string The URI's fragment
40
     */
41
    protected $_fragment;
42
43
    /**
44
     * @var string The URI's host
45
     */
46
    protected $_host;
47
48
    /**
49
     * @var string The URI's port
50
     */
51
    protected $_port;
52
53
    /**
54
     * @var string The URI's specified user
55
     */
56
    protected $_username;
57
58
    /**
59
     * @var string The URI's specified password
60
     */
61
    protected $_password;
62
63
64
    /**
65
     * Constructs a new URI
66
     *
67
     * @param string $uri 		The URI
68
     * @return boolean			true if success
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
69
     */
70
    public function __construct($uri = null)
71
    {
72
        if (isset($uri) && !URIHelper::isValid($uri)) {
73
            throw new \InvalidArgumentException("Invalid URI");
74
        }
75
76
        $this -> _uri = $uri;
77
        $this -> setQuery(URIHelper::getQueryParams($uri));
78
        $this -> setPath();
79
        $this -> setFragment();
80
        $this -> setUser($this -> getUsername());
81
    }
82
83
    /**
84
     * Return the URI's scheme.
85
     *
86
     * @return string
87
     */
88
    public function getScheme()
89
    {
90
        if (!isset($this -> _scheme) || $this -> _scheme === null) {
91
            return '';
92
        }
93
94
        return $this -> _scheme;
95
    }
96
97
    /**
98
     * Returns the user authority in the "[user-info@]host[:port]" format.
99
     *
100
     * @param type name 		description
101
     * @return type 				description
102
     */
103
    public function getAuthority()
104
    {
105
        $userInfo = $this -> getUserInfo();
106
        $port = $this -> getPort();
107
108
        return ($userInfo ? $userInfo . '@' : '') .
109
            $this -> getHost() .
110
            (null !== $port ? ':' . $port : '');
111
    }
112
    
113
    /**
114
     * Returns user info in the "username[:password]" format.
115
     *
116
     * @return string
117
     */
118
    public function getUserInfo()
119
    {
120
        $userInfo = $this -> getUsername();
121
        $password = $this -> getPassword();
122
        if ('' !== $userInfo && '' !== $password) {
123
            $userInfo .= ':' . $password;
124
        }
125
126
        return $userInfo;
127
    }
128
129
    /**
130
     * Retrieves the username (user=) specified in the URI.
131
     *
132
     * @return string
133
     */
134 View Code Duplication
    public function getUsername()
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...
135
    {
136
        $params = URIHelper::getQueryParams($this -> _uri, false);
137
        if (array_key_exists('username', $params)) {
138
            return $params['username'];
139
        }
140
141
        return '';
142
    }
143
144
    /**
145
     * Retrieves the password specified in the URI.
146
     *
147
     * @return string
148
     */
149 View Code Duplication
    public function getPassword()
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...
150
    {
151
        $params = URIHelper::getQueryParams($this -> _uri, false);
152
        if (array_key_exists('password', $params)) {
153
            return $params['password'];
154
        }
155
156
        return '';
157
    }
158
159
    /**
160
     * Retrieves the URI's host.
161
     *
162
     * @return string
163
     */
164
    public function getHost()
165
    {
166
        $host = strtolower(Server::getValue('SERVER_NAME'));
167
        
168
        return $host;
169
    }
170
171
    /**
172
     * Retrieves the URI's port.
173
     *
174
     * @return string
175
     */
176
    public function getPort()
177
    {
178
        $port = Server::getValue('SERVER_PORT');
179
180
        return $port;
181
    }
182
183
    /**
184
     * Returns the URI's path.
185
     *
186
     * @return string
187
     */
188
    public function getPath()
189
    {
190
        return $this -> _path;
191
    }
192
193
    /**
194
     * Sets the URI's path.
195
     *
196
     * @return void
197
     */
198
    protected function setPath()
199
    {
200
        // is this the front end controller?
201
        $path = URIHelper::percentEncode(Server::getValue('PHP_SELF'));
202
203
        $path = str_replace('index.php/', '', $path); // rooted
204
        $path = str_replace('index.php', '', $path); // empty
205
206
        $this -> _path = $path;
207
    }
208
209
    /**
210
     * Retrieve the query string of the URI.
211
     *
212
     * If no query string is present, this method MUST return an empty string.
213
     *
214
     * The leading "?" character is not part of the query and MUST NOT be
215
     * added.
216
     *
217
     * The value returned MUST be percent-encoded, but MUST NOT double-encode
218
     * any characters. To determine what characters to encode, please refer to
219
     * RFC 3986, Sections 2 and 3.4.
220
     *
221
     * As an example, if a value in a key/value pair of the query string should
222
     * include an ampersand ("&") not intended as a delimiter between values,
223
     * that value MUST be passed in encoded form (e.g., "%26") to the instance.
224
     *
225
     * @see https://tools.ietf.org/html/rfc3986#section-2
226
     * @see https://tools.ietf.org/html/rfc3986#section-3.4
227
     * @return string The URI query string.
228
     */
229
    public function getQuery()
230
    {
231
        if (isset($this -> _query) && null !== $this -> _query) {
232
            return $this -> _query;
233
        }
234
235
        $query = Server::getValue('QUERY_STRING');
236
237
        // if not defined, attempt to resolve it
238
        if ('' === $query) {
239
            if (strstr($this -> _uri, '?')) {
240
                $query = substr($this -> _uri, strpos($this -> _uri, '?') + 1);
241
            }
242
        }
243
244
        return URIHelper::percentEncode($query);
245
    }
246
247
    /**
248
     * Retrieves the URI's fragment.
249
     *
250
     * @return string
251
     */
252
    public function getFragment()
253
    {
254
        return $this -> _fragment;
255
    }
256
257
    protected function setFragment($fragment = null)
258
    {
259
        $this -> _fragment = (isset($fragment) && null !== $fragment) ?
260
            $this -> _fragment = $fragment :
261
            $this -> _fragment = URIHelper::getQueryFragment($this -> _uri);
262
    }
263
264
    /**
265
     * Return an instance with the specified scheme.
266
     *
267
     * This method MUST retain the state of the current instance, and return
268
     * an instance that contains the specified scheme.
269
     *
270
     * Implementations MUST support the schemes "http" and "https" case
271
     * insensitively, and MAY accommodate other schemes if required.
272
     *
273
     * An empty scheme is equivalent to removing the scheme.
274
     *
275
     * @param string $scheme The scheme to use with the new instance.
276
     * @return static A new instance with the specified scheme.
277
     * @throws \InvalidArgumentException for invalid or unsupported schemes.
278
     */
279
    public function withScheme($scheme)
280
    {
281
        $clone = clone $this;
282
        $clone -> setScheme($scheme);
283
284
        return $clone;
285
    }
286
287
    protected function setScheme($scheme)
288
    {
289
        $this -> _scheme = $scheme;
290
    }
291
292
    /**
293
     * Return an instance with the specified user information.
294
     *
295
     * This method MUST retain the state of the current instance, and return
296
     * an instance that contains the specified user information.
297
     *
298
     * Password is optional, but the user information MUST include the
299
     * user; an empty string for the user is equivalent to removing user
300
     * information.
301
     *
302
     * @param string $user The user name to use for authority.
303
     * @param null|string $password The password associated with $user.
304
     * @return static A new instance with the specified user information.
305
     */
306
    public function withUserInfo($user, $password = null)
307
    {
308
        $clone = clone $this;
309
        $clone -> setUser($user);
310
        $clone -> setPassword($password);
311
312
        return $clone;
313
    }
314
315
    protected function setUser($user)
316
    {
317
        $this -> _username = $user;
318
    }
319
320
    protected function setPassword($password)
321
    {
322
        $this -> _password = $password;
323
    }
324
325
    /**
326
     * Return an instance with the specified host.
327
     *
328
     * This method MUST retain the state of the current instance, and return
329
     * an instance that contains the specified host.
330
     *
331
     * An empty host value is equivalent to removing the host.
332
     *
333
     * @param string $host The hostname to use with the new instance.
334
     * @return static A new instance with the specified host.
335
     * @throws \InvalidArgumentException for invalid hostnames.
336
     */
337
    public function withHost($host)
338
    {
339
        $clone = clone $this;
340
        $clone -> _host = $host;
341
342
        return $clone;
343
    }
344
345
    /**
346
     * Return an instance with the specified port.
347
     *
348
     * This method MUST retain the state of the current instance, and return
349
     * an instance that contains the specified port.
350
     *
351
     * Implementations MUST raise an exception for ports outside the
352
     * established TCP and UDP port ranges.
353
     *
354
     * A null value provided for the port is equivalent to removing the port
355
     * information.
356
     *
357
     * @param null|int $port The port to use with the new instance; a null value
358
     *     removes the port information.
359
     * @return static A new instance with the specified port.
360
     * @throws \InvalidArgumentException for invalid ports.
361
     */
362
    public function withPort($port)
363
    {
364
        if (!URIHelper::isPortValid($port)) {
365
            throw new \InvalidArgumentException("Invalid port. The port must be within the TCP and UDP port ranges.");
366
        }
367
        
368
        $clone = clone $this;
369
        $clone -> setPort($port);
370
371
        return $clone;
372
    }
373
374
    protected function setPort($port)
375
    {
376
        $this -> _port = $port;
377
    }
378
379
    /**
380
     * Return an instance with the specified path.
381
     *
382
     * This method MUST retain the state of the current instance, and return
383
     * an instance that contains the specified path.
384
     *
385
     * The path can either be empty or absolute (starting with a slash) or
386
     * rootless (not starting with a slash). Implementations MUST support all
387
     * three syntaxes.
388
     *
389
     * If the path is intended to be domain-relative rather than path relative then
390
     * it must begin with a slash ("/"). Paths not starting with a slash ("/")
391
     * are assumed to be relative to some base path known to the application or
392
     * consumer.
393
     *
394
     * Users can provide both encoded and decoded path characters.
395
     * Implementations ensure the correct encoding as outlined in getPath().
396
     *
397
     * @param string $path The path to use with the new instance.
398
     * @return static A new instance with the specified path.
399
     * @throws \InvalidArgumentException for invalid paths.
400
     */
401
    public function withPath($path)
402
    {
403
        $clone = clone $this;
404
        if (!URIHelper::isPathValid($path)) {
405
            throw new \InvalidArgumentException("Invalid path.");
406
        }
407
408
        $clone -> setPath($path);
0 ignored issues
show
The call to Uri::setPath() has too many arguments starting with $path.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
409
410
        return $clone;
411
    }
412
413
    public function withQuery($query)
414
    {
415
        if (!URIHelper::isQueryValid($query)) {
416
            throw new \InvalidArgumentException("Invalid query.");
417
        }
418
419
        $clone = clone $this;
420
        $clone -> setQuery($query);
421
422
        return $clone;
423
    }
424
425
    public function setQuery($query)
426
    {
427
        if (!is_string($query)) {
428
            throw new \InvalidArgumentException("Query must be a string.");
429
        }
430
431
        $this -> _query = $query;
432
    }
433
434
    public function withFragment($fragment)
435
    {
436
        $clone = clone $this;
437
        $clone -> setFragment($fragment);
438
439
        return $clone;
440
    }
441
442
    public function __toString()
443
    {
444
        if (is_string($this -> _uri)) {
445
            return $this -> _uri;
446
        }
447
448
        return '';
449
    }
450
}
451